I have a Qt dialog and there is a slider in it, when the dialog is initialized the slider will be set a value. In order to remind the user what is the default value, I want to add a mark to the slider, just draw a line or a triangle above the handle. Here, the slider should be of QSlider type, that means I can't implement a customized control derived from QSlider. Is there any way to realize it ?
Asked
Active
Viewed 6,273 times
3
-
You mean handle is positioned somewhere along slider range but you want to emphasize another position by drawing some kind of marker? – Masci Mar 21 '12 at 10:46
-
@Masci : I want to emphasize the default value of the slider, when user drags the handle, they can still see the original value of the slider since there is a mark for initial value. – Royt Mar 21 '12 at 10:55
3 Answers
7
I'm not clear why you can't derive a control from QSlider
. You can still treat it like a QSlider
, just override the paintEvent
method. The example below is pretty cheesy, visually speaking, but you could use the methods from QStyle
to make it look more natural:
#include <QtGui>
class DefaultValueSlider : public QSlider {
Q_OBJECT
public:
DefaultValueSlider(Qt::Orientation orientation, QWidget *parent = NULL)
: QSlider(orientation, parent),
default_value_(-1) {
connect(this, SIGNAL(valueChanged(int)), SLOT(VerifyDefaultValue(int)));
}
protected:
void paintEvent(QPaintEvent *ev) {
int position = QStyle::sliderPositionFromValue(minimum(),
maximum(),
default_value_,
width());
QPainter painter(this);
painter.drawLine(position, 0, position, height());
QSlider::paintEvent(ev);
}
private slots:
void VerifyDefaultValue(int value){
if (default_value_ == -1) {
default_value_ = value;
update();
}
}
private:
int default_value_;
};
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
DefaultValueSlider *slider = new DefaultValueSlider(Qt::Horizontal);
slider->setValue(30);
QWidget *w = new QWidget;
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(slider);
layout->addStretch(1);
w->setLayout(layout);
QMainWindow window;
window.setCentralWidget(w);
window.show();
return app.exec();
}
#include "main.moc"

Dave Mateer
- 17,608
- 15
- 96
- 149
-
-
Although `QStyle:: sliderPositionFromValue` does the math for us, it doesn't take into account the margin. The default tick drawing routines indent the first and last ticks. But sliderPositionFromValue does not, meaning that ticks drawn with drawLine at that position will not match the Slider position. – automorphic Feb 21 '20 at 03:36
-
1A quick fix is to use "width() - 20" for the tick position calculation, and add 10 to the returned position: `int position = 10 + QStyle::sliderPositionFromValue(minimum(), maximum(), tickXPos, width() - 20);` Surely there is some way to get this margin from Qt, rather than hard-coding it?!! – automorphic Feb 21 '20 at 04:17
2
Easiest way I can think off is:
Add QSlider to QSlider (like you do it with layouts and QFrames). Slider above will be your current slider (clickable one). Slider below will be your "default tick position" value.
#include <QApplication>
#include <QSlider>
#include <QVBoxLayout>
int main(int argc, char * argv[])
{
QApplication app(argc, argv);
QSlider * defaultValueSlider = new QSlider();
QSlider * valueSlider = new QSlider(defaultValueSlider);
QVBoxLayout * lay = new QVBoxLayout(defaultValueSlider);
lay->setContentsMargins(0, 0, 0, 0);
lay->setSpacing(0);
lay->addWidget(valueSlider);
defaultValueSlider->setRange(0, 100);
valueSlider->setRange(0, 100);
defaultValueSlider->setValue(30);
defaultValueSlider->show();
return app.exec();
}

Kamil Klimek
- 12,884
- 2
- 43
- 58
0
Why do you need to inherit a QSlider to access its public methods?
http://doc.trolltech.com/4.7/qslider.html
You can just call its setTickPosition() in your app.

jdi
- 90,542
- 19
- 167
- 203
-
sorry I didn't express my question clearly. I mean, for example, if the value of the slider is 30, there is only a mark at the position of 30. – Royt Mar 21 '12 at 10:45