Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

tick marks disappear on styled QSlider

I'm using Qt 5.3 and trying to style a QSlider. However, when I apply my style-sheet, the tick marks disappear. Does anyone know how to keep the styling without affecting the tick marks?

Here is the style sheet:

QSlider::groove:horizontal
{
    border: 1px inset #B0B0B0;
    background-color: #EAEAEA;
    height: 2px;
}

QSlider::Handle
{   
    border: 1px solid black;
    background: #B0B0B0;                        
    background-image: url(:/metal_background_small);    
    width: 12px;
    margin: -8px 0;
}

QSlider::Handle:Hover
{   
    border: 1px solid black;
    background: #707070;                        
    background-image: url(:/metal_background_small);    
}

QSlider::sub-page
{
/*  margin: 7px 1px 7px 0px;*/
    height: 2px;
    background: #05bcfe;
}
like image 851
Nicolas Holthaus Avatar asked Dec 17 '14 17:12

Nicolas Holthaus


1 Answers

Qt Style Sheets and tick marks do NOT play nicely together. the simplest solution is to subclass QSlider and re-implement the paint_event.

virtual void paintEvent(QPaintEvent *ev)
{

    QStylePainter p(this);
    QStyleOptionSlider opt;
    initStyleOption(&opt);

    QRect handle = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);

    // draw tick marks
    // do this manually because they are very badly behaved with style sheets
    int interval = tickInterval();
    if (interval == 0)
    {
        interval = pageStep();
    }

    if (tickPosition() != NoTicks)
    {
        for (int i = minimum(); i <= maximum(); i += interval)
        {
            int x = round((double)((double)((double)(i - this->minimum()) / (double)(this->maximum() - this->minimum())) * (double)(this->width() - handle.width()) + (double)(handle.width() / 2.0))) - 1;
            int h = 4;
            p.setPen(QColor("#a5a294"));
            if (tickPosition() == TicksBothSides || tickPosition() == TicksAbove)
            {
                int y = this->rect().top();
                p.drawLine(x, y, x, y + h);
            }
            if (tickPosition() == TicksBothSides || tickPosition() == TicksBelow)
            {
                int y = this->rect().bottom();
                p.drawLine(x, y, x, y - h);
            }

        }
    }

    // draw the slider (this is basically copy/pasted from QSlider::paintEvent)
    opt.subControls = QStyle::SC_SliderGroove;
    p.drawComplexControl(QStyle::CC_Slider, opt);

    // draw the slider handle
    opt.subControls = QStyle::SC_SliderHandle;
    p.drawComplexControl(QStyle::CC_Slider, opt);
}
like image 197
Nicolas Holthaus Avatar answered Oct 31 '22 18:10

Nicolas Holthaus