PDA

View Full Version : QSlider step customize



Kostanev
24th September 2007, 21:50
Hello,

How can I make my slider handle to move on the place where I had clicked (on the slider) instead to move with fixed step?

Thanks!

marcel
24th September 2007, 22:00
Override mousePressEvent and calculate where the click occurred within the slider(the best is to get that in %). Next you must set the corresponding value.

Kostanev
24th September 2007, 22:25
lol I have no idea how to convert the mouse position from pixels to slider position...

marcel
24th September 2007, 22:33
Let's say the user clicks at (100, 50), and the slider geometry is (30, 40, 200, 60).
Then the slider width is 200-30=170px.
Now, clicking at 100 pixels(relative to the slider) means the knob should be moved at 58.82% from the slider value.
So if the slider value goes from 1 to 440, then you should use QSlider:setValue(440*58.82/100).
This should position the know approximately(due to rounding errors) under the mouse cursor.

jpn
24th September 2007, 23:13
I'd give QStyle::styleHint(QStyle::SH_Slider_AbsoluteSetBut tons) a try:

Which mouse buttons cause a slider to set the value to the position clicked on.

jpn
24th September 2007, 23:19
To extend a bit, see Qt Centre wiki: Proxy style (http://wiki.qtcentre.org/index.php?title=Proxy_style) and the following example:


class CustomStyle : public ProxyStyle
{
public:
MyStyle(const QString& baseStyle) : ProxyStyle(baseStyle) { }

int styleHint(QStyle::StyleHint hint, const QStyleOption* option = 0, const QWidget* widget = 0, QStyleHintReturn* returnData = 0) const
{
if (hint == QStyle::SH_Slider_AbsoluteSetButtons)
return (Qt::LeftButton | Qt::MidButton | Qt::RightButton);
return ProxyStyle::styleHint(hint, option, widget, returnData);
}
};

BatteryCell
25th September 2007, 05:02
Take a look at

QStyle::sliderValueFromPosition ( int min, int max, int position, int span, bool upsideDown = false )

So:

void CustomSlider::mouseReleaseEvent(QMouseEvent * event) {
setValue(QStyle::sliderValueFromPosition(minVal,ma xVal,event->x(),width(),0));
}

alexi_nedo
10th March 2011, 17:08
By combining all of the above answers, I have applied like the following way, and it worked:

1. Install an event filter for QSlider m_slider (QSlider* m_slider = new QSlider())


myGUI::myGUI(QWidget *parent)
: QWidget(parent),

{
ui.setupUi(this);

// m_Slider is a QSlider*
m_slider->installEventFilter(this);

//...

}

2. In the event filter change position of Slider's handle:

bool myGUI::eventFilter(QObject* watched, QEvent* event)
{
if (watched == m_slider && event->type() == QEvent::MouseButtonRelease )
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
m_slider->setValue(QStyle::sliderValueFromPosition(m_slider->minimum(), m_slider->maximum(), mouseEvent->x(), m_slider->width()));
}

return false;

}

astodolski
10th December 2013, 21:34
Slick! That worked great. Just what I was looking for :D

t_3
14th July 2015, 13:47
just a note in case someone stumbles across this:

using the widget _width_ as _span_ parameter in QStyle::sliderValueFromPosition() is probably not going to return correct values.

for example in a horizontal slider the handle has a particular width, thus the end positions for the min/max values are reduced at least by half the width of the handle - that's just why the parameter is actually called span - as it needs to reflect the space that is available for sliding the handle center, not the total width of the slider widget (of course the handle needs to fit within the total width of the widget when set to min/max).

it is also possible for a style/proxy style to change this "sliding span" further by modifying pixel metric values, thus this also might need to be accounted, and since this method is static it of course can't know about all the stuff like the current style handle width/height and/or pixel metrics (if you look at the sources of QStyle, this method does just some simple math, that doesn't deal with the actual geometry of the slider).