Custom (pixmap) slider handle for QScrollBar
Having accomplished something similar for a QSlider, I thought it'd be simple. However, I've overriden drawComplexControl, subControlRect, hitTestComplexControl and pixelMetric, and I still encouter two related bugs: when dragging the handle, the handle moves to other places than what the mouse cursor points to, and the handle, instead of being confined to the slider groove, manages to escape the QScrollBar and overwrite its arrows.
I'm guessing both of these is because somehow I've screwed up the calculation of pixel position to slider position to value to screen position, but I can't figure out where. Below are cleaned up code snippets.
Code:
void PictureScrollbarStyle
::drawComplexControl(ComplexControl control,
const QStyleOptionComplex* option,
{
-snip-
//drawing the handle
QRect Pos
= subControlRect
(CC_ScrollBar, option, SC_ScrollBarSlider, widget
);
painter->drawPixmap(Pos , *handlePicture);
-snip-
}
Code:
SubControl subControl,
const QWidget* widget
) const{
-snip-
if (SC_ScrollBarSlider == subControl)
{
int h = handlePicture->height() / 2;
int span = StyleOptions->maximum - StyleOptions->minimum;
float ratio = (float)StyleOptions->rect.height() / (float)span;
int position = (int)(StyleOptions->sliderPosition * ratio);
QRect result
(0, position
- h, handlePicture
->width
(), handlePicture
->height
());
return result.
isValid() ? result
: QRect(0,
0,
0,
0);
}
-snip-
}
Code:
const QPoint
& pos,
const QWidget* widget
) const {
-snip-
r = subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
if (r.isValid() && r.contains(pos))
{
return SC_ScrollBarSlider;
}
return SC_ScrollBarGroove;
}
pixelMetric code isn't attached because debug prints show it's not used.
Thanks in advance.
Re: Custom (pixmap) slider handle for QScrollBar
Glad to see I'm not the only one stumped by this. I eventually worked around the problem by calling QApplication::style()->subControlRect for the handle subrect, made slight adjustments to top and bottom if needed to accomodate my slightly larger arrow graphics, and used a pixmap that looks good when scaled for handle graphics. The whole value/position thing is pretty tangled instead Qt's code (namely qstyle's positionFromValue and qlistwidget's code), so the setRange fix I used for QSlider couldn't work.