[Qt-interest] QSlider paint event: drawing the handle

eric.kort at exsilico.com eric.kort at exsilico.com
Mon Jun 13 20:24:49 CEST 2011


On Sat, Jun 11, 2011 at 10:17 AM, Mark Liversedge <liversedge at gmail.com> wrote:
> I came across the same issue - it is the Mac style not qxtspanslider that is at fault. I gave up trying to workaround that and just set the style to QCleanlooksStyle on a Mac.
>
> If you can find a nice workaround to get a Mac look and feel working I would love to see it, we use the qxtspanslider in GoldenCheetah to select a range in time-series plots.
>
> Mark

So I looked at the qmac style source, and it uses Apple's Human
Interface API (HITheme), as well it should!  The problem (and perhaps
this is what Mark was originally referring to) is that the HITheme
does not provide for much granularity when drawing "track" items,
including sliders and scroll bars.  It assumes you want the "track"
(e.g., the slider groove or the "bar" of the scroll bar.) So it isn't
straightforward to skip drawing of the "track" within the mac style's
QStylePainter::drawComplexControl.  (There is a
HIThemeGetTrackThumbShape() function defined the HITheme.h that could
probably be used to get the image and then draw it?)

BUT, you can always set the clip rectangle on the second draw, and
QStyle will conveniently tell you where the rect of the handle is.  So
for now, this workaround will work (obviously you could skip the
#ifdef and just set the clip rectangle for EVERY platform, but since
it feel like a kludge I restrict it to the OS which needs it :] )

void DoubleSlider::paintEvent(QPaintEvent *event)
{
   QStylePainter painter(this);
   QStyleOptionSlider opt;
   opt.init(this);
   opt.orientation = Qt::Horizontal;
   opt.minimum = 0;
   opt.maximum = 100;
   opt.sliderPosition = 20; // arbitrary value for demonstration purposes
   opt.sliderValue = 20;
   opt.subControls = QStyle::SC_SliderHandle;
   painter.drawComplexControl(QStyle::CC_Slider, opt);
   opt.sliderPosition = 40; // a second arbitrary value
   opt.sliderValue = 40;
#ifdef Q_OS_MAC
   QRect clip = style()->subControlRect(QStyle::CC_Slider, &opt,
QStyle::SC_SliderHandle, this);
   painter.setClipRect(clip);
#else
   opt.subControls = QStyle::SC_SliderHandle;
#endif
   painter.drawComplexControl(QStyle::CC_Slider, opt);
   painter.end();
}

-Eric





More information about the Qt-interest-old mailing list