Subclassing QSlider with handle as a Widget



  • Hello,

    I want to draw a custom widget in the slider handle, I have no idea how to do that?
    Do you think I could achieve this by subclassing QSlider or QAbstractSlider?

    Cheers,



  • It depends what you want to achieve exactly. If you subclass, you also inherit the complete API and thus the identity of QSlider. That is, your new widget will be a slider, for all practical purposes. If you don't want that, consider using QStyle to just render the parts of the slider that you need instead.



  • Yes, is perfectly doable by subclassing QSlider.
    See my slider implementation for example :
    !http://s22.postimg.org/4c9p4p0qp/Slider.png(my Slider)!

    The two green areas are two QLabels

    edit: Andre was faster :-)



  • Thank you very much for your answers.
    I want to have the behaviour of a slider I just want the handle to be a rectangle widget to draw whatever I want inside.

    Looks like your example is perfect cincirin, could you please tell me with 2 lines of codes how you acheieved that?
    Can you move these two QLabels?
    I cant figure how to access the handle by the QSlider class ....



  • Could you tell us what you want to achieve? What would you like to put on the handle? If it is just a label, it might be easier to render that content yourself in your QSlider subclass.



  • bq. could you please tell me with 2 lines of codes how you acheieved that?

    Of course I can, but as Andre said is better to tell us what are you trying to achieve and what are your attempts to implement them ?

    bq. Can you move these two QLabels?

    Yes any widget can be moved, just set the widget position depending on your requirements.

    So in short here is my implementation:

      • subclass QSlider and create two labels in constructor having parent this slider
      • in slider resizeEvent, move the two labels in respect with new slider width
      • for the two labels install event filter ON slider object ( or you can subclass labels to implement mouse press/move/release )
      • in slider event filter I check for mouse press/move/release for the two labels and move them accordingly


  • Hello,

    I really appreciate your help.
    I want to draw an audio sinus wave in a SinusWidget to be positonned on a time line widget.
    This SinusWidget will be able to move horizontally from left to right depending on when you want the sinus wave to be played.
    I should also have events connected to the SinusWidget to be able to change its width.

    Because of this, I was thinking about a slider to provide embedded SinusWidget via the handle.

    Something like this.

    initial example :
    ISINUS WIDGETI-----------------------------------------

    position changed:
    -----------------------------ISINUS WIDGETI------------

    width changed:
    ----------------ISINUS ________ WIDGETI-----------------

    What do you think about it?



  • I'm sorry but I don't understand exactly what is your requirement.
    In my example I really needed a slider with three values and signals when one of the three value is changed.
    From what I understand you only need a "widget" which is moved horizontally from left to right. Is this correct ? If yes, you can use slider directly and either use style sheets or implement a custom style to draw/paint slider "widget" value.



  • Cincirin,

    Yes I need to move a widget from left to right within a certain range.
    I had the idea of a slider because it looks convenient for what I want to achieve ;) (left to right implemented, start and end positions, etc ...)
    I am sorry if I explained it in the wrong way.

    [quote author="cincirin" date="1391516376"]If yes, you can use slider directly and either use style sheets or implement a custom style to draw/paint slider “widget” value.[/quote]

    Here is my issue, I don't know how to paint the widget on the slider's handle. I don't think stylesheet can achieve that does it?
    And for custom style, how to access the handle.

    The normal way to go if the slider's handle was a class would be to subclass it and reimplement the paint method.
    I am not familiar with QStyle at all, it's probably the reason why I don't know how to do this ....



  • "Customizing QSlider":http://qt-project.org/doc/qt-4.8/stylesheet-examples.html#customizing-qslider

    See how to customize the slider groove and slider handle



  • [quote author="cincirin" date="1391517392"]"Customizing QSlider":http://qt-project.org/doc/qt-4.8/stylesheet-examples.html#customizing-qslider

    See how to customize the slider groove and slider handle[/quote]

    :)

    Cincirin, I know about this already :)
    But this is just to customize the appearance of the handle, not transforming it to a custom widget on which you can add events, etc ...
    Or am I mistaken?



  • Ok, what events do you need ?
    Isn't the default "signals":http://qt-project.org/doc/qt-5/qabstractslider.html#signals what you need ?



  • These events are enough yes, but I need them on the slider's handle, not on the slider itself ;)



  • bq. I need them on the slider’s handle

    Which one exactly ?
    Basically you can subclass slider, obtain a rect of the handle style()->subControlRect and from here you can filter all mouse events from handle only. For paint of course you can reimplement paintEvent, but with style sheet is easily. What other events do you need ?



  • I need these ones on the handle:
    virtual void mouseDoubleClickEvent(QMouseEvent * event)
    virtual void mouseMoveEvent(QMouseEvent * event)
    virtual void mousePressEvent(QMouseEvent * event)
    virtual void mouseReleaseEvent(QMouseEvent * event)
    virtual void moveEvent(QMoveEvent * event)

    If I understand you, you want to "render" the CustomWidget without embedding it to the handle and filter the events on the rectangle zone and not on the customwidget?



  • Yes you can reimplement all of these events in QSlider subclass, and filter all mouse events for handle rect only. Thats all ...
    @
    if (style()->subControlRect(etc).contains(event->pos())
    @



  • ok :)

    And for painting the customwidget, you just instantiate it into the paint method of the subclasses slider and parent it to the subclassed slider?



  • In my example with yes, but I needed three handles not one. With only one handle you can use QSlider signals, events and style(sheets) without any other additional widget(s)



  • And how to you render the customWidget with stylesheet?



  • I'm not using stylesheet in example posted. The default slider handle is rendering by application style and the other two are QLabels with image pixmap.



  • Yes it was as I thought. So how do I do ? :D



  • What's wrong by subclassing QSlider and reimplement all mouse events you need ? Also you can paint the slider handle either in paint event or using stylesheet. So you have a complete control on slider handle.



  • Hello again,

    I didn't know we could render a widget with QPainter, I never did like that in the past.
    You are talking about :

    painter->begin(mycustomwidget); right?

    Looks like there is also itemChange if I forget about the idea of subclassing a QSlider ....



  • I think you misunderstood me ( or maybe I misunderstand you :-) )
    Why do you need a "customwidget" at all ? Consider that your "customwidget" is slider handle. You can render this "handle" in the way you want, also you can intercept mouse events for slider and filter these for "handle" rect.



  • Its probably me who misunderstood :D
    I wanted a separated widget for architecture reasons, to make it modular.
    Lets say that tomorrow I decide that it will not be a slider but something else.
    Or I want to render this customwidget in another view in my software ...

    There are a lot of reasons :)


Log in to reply
 

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