How do I subclass QDial to show notches values ?



  • Hi guys,

    I would like to show values in QDial.
    But not number, I would like to "set" a string for each value..
    for example,
    1 => Hey
    2 => Hello
    3 => Hi
    etc..
    And in my GUI, for every notches we will see hey, hello, hi etc..

    But I don't know how to do it...


  • Qt Champions 2016

    Hi
    What about just placing a label next to the dial (or on top of it)
    hook up the void valueChanged(int value)
    to a slot in main
    and then simple change the text in the label when dial is changed?



  • Because I need to see all of the values...
    And I can't put x label for x values, because I load a XML which say how many QDial I need ^^'
    and the values aren't the same for all of the QDial...

    (sorry if my english is bad x) )


  • Qt Champions 2016

    Hi
    Your English is fine but its not clear how this Dial should look like

    So INSTEAD of values/small ticks on the Dial, you want text `?
    So first little tick is Hello etc ?



  • @mrjj
    Something like that :
    Gyazo Link


  • Qt Champions 2016

    @Punt
    Ok
    You can sublass it and override the paintEvent
    make it paint as normal, and then paint the text on top.
    But you show 4 texts, do you have more for real app?



  • @mrjj
    I would like to have a subclass which will work with 3 to 6 values..

    Because, at the end, my app need to be adaptable/adjustable as the user(not me) want !


  • Qt Champions 2016

    Hi
    Well then subclass will work best as you can add support
    for having a list of TickTexts or what u call them :)



  • @mrjj said:

    @Punt
    Ok
    You can sublass it and override the paintEvent
    make it paint as normal, and then paint the text on top.
    But you show 4 texts, do you have more for real app?

    I know how to subclass & override, but "make it paint as normal and then paint the text", I don't have any idea how to do it ...


  • Qt Champions 2016

    @Punt
    Oh sorry being unclear
    When you have overridden paint
    in top you call the base class
    void mycooldial::paintEvent( ..
    QDial::PaintEvent(event); << call the normal paint

    then after u paint text on top of it.



  • @mrjj
    OK here I am :

    .h :

    #ifndef CUSTOMDIAL_H
    #define CUSTOMDIAL_H
    
    #include <QObject>
    #include <QDial>
    
    class CustomDial : public QDial
    {
        Q_OBJECT
    
    public:
    
        CustomDial(QWidget * parent = nullptr,
                   double knobRadius = 5,
                   double knobMargin = 5);
    
    private:
    
        virtual void paintEvent(QPaintEvent*pe) override;
    
    };
    
    #endif // CUSTOMDIAL_H
    
    

    .cpp :

    #include "customdial.h"
    
    CustomDial::CustomDial(QWidget* parent,
                           double knobRadius,
                           double knobMargin)
    : QDial(parent)
    {
        // Default range
        QDial::setRange(0,100);
    }
    
    void CustomDial::paintEvent(QPaintEvent* pe)
    {    QDial::paintEvent(pe);
    
    }
    
    

    It seems to work, I have my QDial then I'll try to add my text...

    But I have :

    QMetaObject::connectSlotsByName: No matching signal for on_pushButton_pressed()
    QMetaObject::connectSlotsByName: No matching signal for on_pushButton_clicked()
    QMetaObject::connectSlotsByName: No matching signal for on_pushButton_released()
    QMetaObject::connectSlotsByName: No matching signal for on_dial_valueChanged(int)
    

  • Qt Champions 2016

    Hmm
    you dont show any connect statements?

    So this from other part of project.

    This might happen if you add slot by right clicking in Creator and then later rename slot or the button/widget
    Its not related to the subclass as such.



  • @mrjj
    Oh sorry my bad to disturb you for this..
    This is SLOT that I used earlier to try things with QDial --'

    Ok I'll try to paint my text now :)


  • Qt Champions 2016

    @Punt
    Np. :)



  • Ok, I understand how it works.. I have an idea to determinate the position of my texts (unit cercle I guess).

    But I have a problem, because for example (with a QDial 100x100) :

    • if I add text in (0,50) a part of the text will be on the QDial..
    • if I add text in (-10,50), a part of the text will be cut

    I guess I have to extend the painting zone.. but I don't find anything...


  • Qt Champions 2016

    @Punt
    Hi the
    "Painting zone" is the size of the QDial
    You cannot paint outside it using -100 for x
    It clip clip as you saw.
    You cannot increase this area unless its ok the QDial also becomes bigger.



  • @mrjj
    Maybe I can reduce the QDial then ? Like the radius of the circle ?

    Or last idea : I create a new class, in which I put an "aera" like a Widget (?), I add a QDial and I draw my "notches-text-values" (Still don't know how to call it xDD)


  • Qt Champions 2016

    @Punt
    well maybe. i dont think so.
    I think it uses all its area.
    else u need to copy the paint function and alter it to allow
    to paint smaller than the area.
    You should look in source and see what it uses to better understand it.


  • Qt Champions 2016

    sorry I miss last part.

    Yes also option to make a composite class where u have QDial in center ( in a layout) and
    let ur class paint on top of it all.



  • @mrjj
    I think I'll go for it !
    It's the easiest solution I guess...

    I'm done for today, I'll try it tomorrow :)
    Thanks :)


  • Qt Champions 2016

    but since you already subclassed it, why not make it work 100% like u want?
    Also need to be able to give list for the "tick words" etc.
    So find the source and see the paitnevent
    maybe its easy to modify for what u want.


  • Qt Champions 2016

    void QDial::paintEvent(QPaintEvent *)
    {
    QStylePainter p(this);
    QStyleOptionSlider option;
    initStyleOption(&option);
    p.drawComplexControl(QStyle::CC_Dial, option);
    }

    So u can just change option.rect ( check name)
    and you can control the size of the dial.



  • @mrjj said:

    but since you already subclassed it, why not make it work 100% like u want?
    Also need to be able to give list for the "tick words" etc.
    So find the source and see the paitnevent
    maybe its easy to modify for what u want.

    If I create a composite class, I don't need anymore my subclass...
    Well I don't know, I'll check tomorrow if it's easy (Because i'll probably have to change another thing on a QDial => but that's another thing x) )

    I guess i'll update this topic tomorrow, so if someone has another idea, I take it :)

    Edit for your last message : I'll check tomorrow, I go home and I can't work there :p

    See you


  • Qt Champions 2016

    before u try composite, please try adjust paint first.
    So little code.



  • @mrjj said:

    void QDial::paintEvent(QPaintEvent *)
    {
    QStylePainter p(this);
    QStyleOptionSlider option;
    initStyleOption(&option);
    p.drawComplexControl(QStyle::CC_Dial, option);
    }

    So u can just change option.rect ( check name)
    and you can control the size of the dial.

    I can't do "option.something" ...


  • Qt Champions 2016



  • @mrjj
    Now the problem is I can extend the area and write text in the right and in the bottom of the QDial (because the QDial is drawn (good english ?!) in the left-top (0,0) ). And I don't have any idea how to change that.. I searched if there is something like the position where qt draw of something like that, but didn't find it .. --'


  • Qt Champions 2016

    hi
    Not tested myself.
    option.rect should control where QDial is
    and the normal rect is your widget.

    So if u set option.rect before
    p.drawComplex

    U should be able to move it around?



  • @mrjj
    Look, if I

    option.rect.setX(20)
    

    this is just moving one part of the QDial --'
    Gyazo

    And what do you mean about the normal rect ?

    The only rect I have is option.rect no ?!


  • Qt Champions 2016

    @Punt
    Option has rect yes, used for the drawComplexControl call.
    You own widget, also has rect, simply called rect or this->rect
    which is the real area since the QDial is just painted.



  • @mrjj

        rect().setRect(0,0,200,200);
        option.rect.setRect(30,30,100,100);
        p.drawText(120,120,"(120,120)");
        p.drawText(30,30,"(30,30)");
        p.drawText(200,200,"(200,200)");
    

    => Gyazo

    I don't find anything to move ticks ...


  • Qt Champions 2016

    Hmm
    so it dont use option.rect() for the tick drawing.
    Strange.

    Alternatively
    new a layout
    set to your widget
    New a QDial
    add to layout
    adjust layout margins to get room for text.
    Paint the text in paintEvent.
    Remove the drawComplexControl etc.



  • @mrjj
    In my subclass ?


  • Qt Champions 2016

    @Punt
    Yes
    In constructor
    so it becomes a composite widget with a normal QDial inside.
    You will also have to create some public signal to use from outside
    since you cannot directly connect to the QDail.


  • Qt Champions 2016

    Hi
    yes that seems to be possible.

    https://www.dropbox.com/s/5hjry2pcb0mpsi2/myqdial.zip?dl=0
    I just did it in Creator for test. Using code in
    CustomDial is smarter.



  • @mrjj

    Sorry was busy...
    I don't understand how to do it..
    I tried, when I want to use layout() this is crashing.. I tried different things but isn't working, I'm tired of this button x)


  • Qt Champions 2016

    @Punt
    Np.
    Did u try test?
    U must create layout first with new
    and assign to ur widget
    else
    layout() returns null.
    something like
    QVBoxLayou *verticalLayout = new QVBoxLayout(this);
    verticalLayout->setContentsMargins(32, 32, 32, 32);
    QDial *dial = new QDial(this); ** might have this as class memeber
    verticalLayout->addWidget(dial);



  • @mrjj said:

    @Punt
    Np.
    Did u try test?
    U must create layout first with new
    and assign to ur widget
    else
    layout() returns null.
    something like
    QVBoxLayou *verticalLayout = new QVBoxLayout(this);
    verticalLayout->setContentsMargins(32, 32, 32, 32);
    QDial *dial = new QDial(this); ** might have this as class memeber
    verticalLayout->addWidget(dial);

    Ok that worked, thanks bro ! now I'll add my texts where I want :)


  • Qt Champions 2016

    super!
    You might need to surface some of the signals from the QDial to make
    it do anything usefull.

    In this regards , please note that u -can- connect signals to signals
    So you can define some new public signals and hook the new signals
    to the QDial signals.
    From outside u can then connect to the new signals.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.