Custom style QSlider problem
Unsolved
General and Desktop
-
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