PDA

View Full Version : Round QSlider



Havard
25th June 2007, 19:32
hi.

I want to make a slider-configuration like this:
http://farm2.static.flickr.com/1350/623130261_411a5dbda3.jpg
Any suggestions on how to make a round QSlider that will allow other sliders to fit inside it?

I don't want it to be continuous, it should have a start and end-point so you can't keep rotating it around. :)

thanks,
Havard

marcel
25th June 2007, 19:46
Yes, really nice.
You should have a custom widget for that. The widget must be all transparent besides the circle and the ellipse knob.

You can achieve this by filling the (rectangular) widget with a transparent pixmap. then draw a circle( inscribed in the widget bounding rect - actually square :)).

For the knob you can simply draw an ellipse and store its bounding rect as a member in the class.
Next you must implement mousePressEvent, mouseReleaseEvent and mouseMoveEvent. These will make possible the interaction with the knob.
For the horizontal and vertical sliders you should use the same class, but add some flags to it that will tell it how to paint the slider( as a circle, horizontal, etc... ).

You can add a valueChanged signal that you emit in mouseMoveEvent, when the user drags the knob and the value changes.

That's how I would do it.

BTW: to make the two smaller sliders fit, you should compute the square inscribed in the circle( its diagonal is equal with the circle diameter ), therefore the length of a slider is sqrt(2)*diameter.

Regards

marcel
25th June 2007, 19:53
Of course, you could use a QGraphicsView also , but this would be efficient only if you want your widget to always look like that ( three sliders ).

Regards

Havard
25th June 2007, 19:57
thank you! Will experiment with that! :)
Any suggestions on an easy way to rotate the knob while it is being turned around? (unless I just make it perfectly round to avoid the trouble...) :)

Havard

EDIT: just saw your suggestions of using QGraphicsView. I guess that solves the rotating-problem then... :)

Havard

marcel
25th June 2007, 20:05
Yes, that is a bit trickier.

You must use QPainter::rotate before you draw the knob and pass it the angle between the mouse vector and the normal vector on the Ox axis.
Having two vectors va and vb, the angle is: angle = acos(va•vb/ |va||vb|), where || is the euclidean norm.

Or, even better, you could compute the angle by working in polar coordinates. Considering the fact that you always move on a circle, then this is pretty straightforward.
You can read this: http://en.wikipedia.org/wiki/Polar_coordinate_system.

EDIT: well, OK then. I guess QGraphicsView will make things easier in a lot of ways.

Regards

marcel
25th June 2007, 20:14
The easiest way to make a graphics item move on a circle when dragged is to reimplement QGraphicsItem::itemChanged and restrict its position to be on the circle when GraphicsItemChange==ItemPositionChange.

Regards