QSlider with SVG groove and knob
-
@Gourmet ... your best bet would be my first suggestion and override the paintEvent and draw your own interface. Trying to use a style sheet takes 5 minutes so it isn't wasting time if you have never tried before. You will know immediately if it does not work. Just make sure your art is in a QRC so you can use the proper notation if you are loading the image.
-
@Buckwheat for QDial stylesheet image replacement doesn't work. I already implemented it with paintEvent() replacement. And some other features added which are impossible by just stylesheet image replacement. This QDial with SVG in .qrc file works fine for me. Even it is Q_PROPERTY adjustable and shows graphics fine in QtDesigner form. Yes, I impemented it as promoted plugin for Designer. I suppose just copy this code for QSlider and just replace and add all needed parts. Nobody did not answer if stylesheet works fine for QSlider and I do not want waste time for dead-end experiments. This all MUST be clearly described in documentation instead of doing "try-and-fail" attempts.
-
/void Slider::paintEvent(QPaintEvent *e) { QSlider::paintEvent(e); QPainter painter(this); QStyleOptionSlider opt; initStyleOption(&opt); QRect handle = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); QPainter* p = &painter; QRect groove = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, this); QRect drawingRect = groove; qreal height = 4; drawingRect.setHeight(height); drawingRect.moveCenter(groove.center()); QPainterPath path; path.addRoundedRect(drawingRect,height / 2.0,height / 2.0); if (opt.state & QStyle::State_Enabled) { p->fillPath(path,grooveColor); }else { p->fillPath(path,grooveColorDisabled); } opt.rect = handle; }
You can then paint your svg in "handle" Rect with http://doc.qt.io/qt-5/qsvgrenderer.html#render-1
-
@Gourmet ... Wow! Your time must be more valuable than any one elses. I think the 5 minute test would not only be a good learning experience but you would get the answer yourself instead of relying on others for the answer. An answer discovered or earned is one that lasts a lifetime!
-
@Buckwheat I hate "try-and-fail" learning technique but prefer learn others experience if it is possible. It is much more productive. Only fools first teach themselves on their own mistakes - smart people learn other's mistakes before action.
-
This world was build from people that tried them self, failed, learned from it and did not give up and just tried again.
They were not fools - they were pioneers ...
-
@Gourmet said in QSlider with SVG groove and knob:
pioneers were those who were not able follow others experience.
So by your logic, all pioneers are fools :)
-
@Gourmet ... Einstein was a fool... hmmm... Darwin was a fool.... hmmm... Entire NASA space field of the 60s were fools... hmmm... I am glad to be in their company! Fools are those who do not learn and grow. Followers often end up going over cliffs. I refer to them as lemmings.
-
This is getting rather philosophical so im going to close it by saying that on the other hand i fully understand if using svg on some knob is just a fast task
and the time needed to understand the docs that fully describe what Widgets supports what tags is wasted as this knowledge cannot be used for anything further in the project -
then the concept of just using other people's experience seems reasonable.However, in that spirit, I hope you will post the paintEvent code so others, feeling like you, can
benefit from your working solution and thereby promote your approach as valid. :) -
@mrjj the SVG requirement is not just a whim. I need it to inedpendently set size and proportions for slider knob and groove. Result must allow resize them separetely in QtDesigner. This doesn't look too musch simple. And it cannot be defenitely made with just stylesheet - this way doesn't allow scale groove and knob separetely.
-
@mrjj I did not tell I will avoid plugin. I created plugin later and it works fine including Q_PROPERTIES support. It is not a problem, I have created several other plugins before. They even are compiled and work as plugins on Linux workstation but they are compiled and work as just shared objects on Android tablet.
Now I need only create proper paintEvent(). But I still cannot get fine result. Code
void SSwidget::paintEvent( QPaintEvent* ) { QPainter painter( this ); painter.setRenderHint( QPainter::Antialiasing, true ); QStyleOptionSlider o; initStyleOption(&o); QRect knobRect = style()->subControlRect(QStyle::CC_Slider, &o, QStyle::SC_SliderHandle, this); QRect grooveRect = style()->subControlRect(QStyle::CC_Slider, &o, QStyle::SC_SliderGroove, this); if( grooveSVG != Q_NULLPTR ) grooveSVG->render( &painter, grooveRect ); if( knobSVG != Q_NULLPTR ) knobSVG->render( &painter, knobRect ); }
Works almost as needed. But groove size has same length as entire widget geometry has. And knob's center moves from most left and right groove edges. In most right and left positions half of knob becomes invisible outside widget rectangle. It is needed not just only shrink groove or stretch widget's rectangle. It is also needed set knob stop points closer to each other like original slider has. If I call QSlider::paintEvent(e) - then I see oroginal slider behind mine. And it moves properly.
-
-
Finaly I did it. I had explored source code of QStyle, QWindowsXPStyle, QFusionStyle, QAndroidStyle, QCommonStyle and some other classes. Solution is - before
QRect knobRect = style()->subControlRect(QStyle::CC_Slider, &o, QStyle::SC_SliderHandle, this); QRect grooveRect = style()->subControlRect(QStyle::CC_Slider, &o, QStyle::SC_SliderGroove, this);
it is needed change size and position of o.rect but after initStyleOption(&o). Call of subControlRect() will calculate new position of knob properly depending from minimum and maximum slider value in margins of o.rect. This solution is much more powerful and flexible than via stylesheet.