Custom style QSlider problem



  • Hi all
    When I wrote my first custom style, I encountered the following problem:
    if the QSlider widget has any of the standard styles (QFusionStyle etc ...), then he behaves correctly. That is: when you click the mouse over the SC_SliderGroove area, SC_SliderHandle will move in the direction of the cursor and stop at it (Curosr).
    How it happens can be seen on the Animation1.gif.

    If the QSlider widget has my custom style (RondoStyle), then he behaves not correctly.
    Under previous conditions, SC_SliderHandle does not stop under the cursor, but moves to the end.
    You can see it on Animation2.gif.

    Below is the code for my custom RondoStyle style and headers for him:

    rondostyle.h

    #ifndef RONDOSTYLE_H
    #define RONDOSTYLE_H
    
    #include <QtWidgets>
    #include <QPainter>
    //#include <QProxyStyle>
    #include <QCommonStyle>
    //#include <QtWidgets/qcommonstyle.h>
    
    class RondoStyle : public QCommonStyle
    {
        Q_OBJECT
    public:
        explicit RondoStyle();
        ~RondoStyle();
    
        virtual void drawComplexControl(ComplexControl       cctrl,
                                   const QStyleOptionComplex* copt,
                                         QPainter*            cpainter,
                                   const QWidget*             cwgt = nullptr) const;
    
        virtual SubControl hitTestComplexControl(ComplexControl       cctrl,
                                   const QStyleOptionComplex* copt,
                                   const QPoint&              cpoint,
                                   const QWidget*             cwgt = nullptr) const;
    
        virtual QRect subControlRect(ComplexControl       cctrl,
                                   const QStyleOptionComplex* copt,
                                         SubControl           subCtrl,
                                   const QWidget*             cwgt = nullptr) const;
    };
    
    #endif // RONDOSTYLE_H
    

    rondostyle.cpp

    #include "rondostyle.h"
    
    RondoStyle::RondoStyle() : QCommonStyle(){}
    
    RondoStyle::~RondoStyle(){}
    
    void RondoStyle::drawComplexControl(ComplexControl cctrl, const QStyleOptionComplex *copt, QPainter *cpainter, const QWidget *cwgt) const{
        if (cctrl == CC_Slider) {
            const QStyleOptionSlider* cOptionSlider = qstyleoption_cast<const QStyleOptionSlider*>(copt);
    
            if (cOptionSlider) {
                cpainter->save();
    
                cpainter->fillRect(subControlRect(cctrl, copt, SC_SliderGroove), QColor(255, 128, 64, 255));
                cpainter->fillRect(subControlRect(cctrl, copt, SC_SliderHandle), QColor(128, 255, 64, 255));
    
                cpainter->restore();
            }
        }
    
        QCommonStyle::drawComplexControl(cctrl, copt, cpainter, cwgt);
    }
    
    QStyle::SubControl RondoStyle::hitTestComplexControl(ComplexControl cctrl, const QStyleOptionComplex *copt, const QPoint &cpoint, const QWidget *cwgt) const{
        if (cctrl == CC_Slider && copt) {
            SubControl sc = SC_None;
    
            if (const QStyleOptionSlider* cOptionSlider = qstyleoption_cast<const QStyleOptionSlider*>(copt)) {
                QRect _tempRect = subControlRect(cctrl, cOptionSlider, SC_SliderHandle);
    
                if (_tempRect.isValid() && _tempRect.contains(cpoint)) {
                    sc = SC_SliderHandle;
                }else{
                    _tempRect = subControlRect(cctrl, cOptionSlider, SC_SliderGroove);
    
                    if (_tempRect.isValid() && _tempRect.contains(cpoint)) {
                        sc = SC_SliderGroove;
                    }
                }
            }
    
            return sc;
        }
    
        return QCommonStyle::hitTestComplexControl(cctrl, copt, cpoint, cwgt);
    }
    
    QRect RondoStyle::subControlRect(ComplexControl cctrl, const QStyleOptionComplex *copt, SubControl subCtrl, const QWidget *cwgt) const{
        if (cctrl == CC_Slider) {
            const QStyleOptionSlider* cOptionSlider = qstyleoption_cast<const QStyleOptionSlider*>(copt);
    
            QRect rectCctrl      = cOptionSlider->rect; // Slider widget rectangle
    
            int iGrooveSize = 30;                    // Size of slider groove
            int iHandleSize = 30;                    // Size of slider groove
    
            switch (subCtrl) {
                case SC_SliderHandle:
                {
                    int _iTempX = QStyle::sliderPositionFromValue(cOptionSlider->minimum, cOptionSlider->maximum, cOptionSlider->sliderPosition, cOptionSlider->rect.width() - iHandleSize, cOptionSlider->upsideDown);
    
                    rectCctrl.setX(_iTempX);
                    rectCctrl.setY(0);
                    rectCctrl.setWidth(30);
                    rectCctrl.setHeight(30);
    
                    return rectCctrl;
                }
                case SC_SliderGroove:
                {
                    rectCctrl.setWidth(rectCctrl.width());
                    rectCctrl.setHeight(iGrooveSize);
                    rectCctrl.setX(0);
                    rectCctrl.setY(0);
    
                    return rectCctrl;
                }
            }
        }
    
        return QCommonStyle::subControlRect(cctrl, copt, subCtrl, cwgt);
    }
    
    

    I use Qt 5.9.1


Log in to reply
 

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