PDA

View Full Version : Custom (pixmap) slider handle for QScrollBar



Antrax
16th October 2006, 10:50
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.


void PictureScrollbarStyle::drawComplexControl(ComplexC ontrol control, const QStyleOptionComplex* option,
QPainter* painter, const QWidget* widget) const
{
-snip-
//drawing the handle
QRect Pos = subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
painter->drawPixmap(Pos , *handlePicture);
-snip-
}



QRect PictureScrollbarStyle::subControlRect(ComplexContr ol control, const QStyleOptionComplex* option,
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-
}



QStyle::SubControl PictureScrollbarStyle::hitTestComplexControl(Compl exControl control, const QStyleOptionComplex* option,
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.

Antrax
17th October 2006, 12:04
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.