Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Changing colors of the QSlider

Changing colors of the QSlider

Scheduled Pinned Locked Moved Solved General and Desktop
qsliderpainteeventcolor change
2 Posts 1 Posters 11.2k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    marlenet15
    wrote on last edited by marlenet15
    #1

    I have two horizontal QSliders and I would like it so that when the user moves the QSlider, it changes color based on the location of the QSlider. There will be three ranges: red for the first 1/3 of the QSlider, yellow for the second 1/3 of the QSlider and the last 1/3 will be green. I am able to show the colors BUT since I used the stylesheet, the ticks that I enabled in order to show where each range is, disappears. I did some research and I saw that you needed to subclass QSlider and use paintevent in order to add the ticks. However, I have tried the following and nothing happens.

    What I have on the .ui file are the 2 QSliders inside a QFrame and the QFrame's stylesheet contains:

    QSlider::groove:horizontal {
    border: 1px solid #bbb;```
    
    height: 10px;
    border-radius: 4px;
    }
    
    QSlider::sub-page:horizontal {
    border: 1px solid #777;
    height: 10px;
    border-radius: 4px;
    }
    
    QSlider::add-page:horizontal {
    background: white;
    border: 1px solid #777;
    height: 10px;
    border-radius: 4px;
    }
    
    QSlider::handle:horizontal {
    background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
        stop:0 #eee, stop:1 #ccc);
    border: 1px solid #777;
    width: 4px;
    margin-top: -2px;
    margin-bottom: -2px;
    border-radius: 4px;
    }
    

    form.h file

    #ifndef FORM_H
    #define FORM_H
    
    #include <QWidget>
    #include <QSlider>
    
    namespace Ui {
    class Form;
    }
    
    class Form : public QWidget
    {
        Q_OBJECT
    
    public:
        explicit Form(QWidget *parent = 0);
        ~Form();
    
    public slots:
        void updateValue(int value);
        void updateValue2(int value);
    
    private:
        Ui::Form *ui;
    };
    

    form.cpp

    #include "form.h"
    #include "ui_form.h"
    #include <QDebug>
    #include "myslider.h"
    
    Form::Form(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::Form)
    {
        ui->setupUi(this);
        int x = 99/3;
    
        ui->horizontalSlider = new MySlider();
       ui->horizontalSlider_2  = new MySlider();
    
        ui->horizontalSlider->setTickInterval(x);
        ui->horizontalSlider_2->setTickInterval(x);
    
        connect(ui->horizontalSlider, SIGNAL(valueChanged(int)),this,SLOT(updateValue(int)));
        connect(ui->horizontalSlider_2, SIGNAL(valueChanged(int)),this,SLOT(updateValue2(int)));
    }
    
    
    void Form::updateValue(int value)
    {
        if(value < 40)
        {
            ui->horizontalSlider->setStyleSheet("QSlider::sub-page:horizontal {background: red;}");
        }
        else if(value >=40 && value < 60)
        {
            ui->horizontalSlider->setStyleSheet("QSlider::sub-page:horizontal {background: yellow;}");
        }
        else
        {
            ui->horizontalSlider->setStyleSheet("QSlider::sub-page:horizontal {background: green;}");
        }
    }
    
    void Form::updateValue2(int value)
    {
    
        if(value < 40)
        {
            ui->horizontalSlider_2->setStyleSheet("QSlider::sub-page:horizontal {background: red;}");
        }
        else if(value >=40 && value < 60)
        {
            ui->horizontalSlider_2->setStyleSheet("QSlider::sub-page:horizontal {background: yellow;}");
        }
        else
        {
            ui->horizontalSlider_2->setStyleSheet("QSlider::sub-page:horizontal {background: green;}");
        }
    }
    
    Form::~Form()
    {
        delete ui;
    }
    
    

    myslider.h

    #ifndef MYSLIDER_H
    #define MYSLIDER_H
    
    #include <QWidget>
    #include <QSlider>
    
    class MySlider : public QSlider
    {
        Q_OBJECT
    public:
        MySlider(QWidget *parent = 0);
    
    protected:
        void paintEvent(QPaintEvent *ev);
    
    };
    
    #endif // MYSLIDER_H
    

    myslider.cpp

    #include "myslider.h"
    #include <QStylePainter>
    #include <QStyleOptionSlider>
    #include <QDebug>
    #include <QSlider>
    
    MySlider::MySlider(QWidget *parent) :
        QSlider(parent)
    {
    }
    
    void MySlider::paintEvent(QPaintEvent *ev)
    {
        QSlider::paintEvent(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 = qRound((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);
    
    }
    
    
    1 Reply Last reply
    0
    • M Offline
      M Offline
      marlenet15
      wrote on last edited by
      #2

      I figured out the answer. I have to create a QSlider from scratch meaning not one created from the ui already.

      So,

          QSlider *slider = new MySlider(Qt::horizontal);
          ui->frameTestLayout->addWidget(slider);
          slider->setFocusPolicy(Qt::NoFocus);
          slider->setTickPosition(QSlider::TicksAbove);
          slider->setTickInterval(number);
      
      1 Reply Last reply
      1

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved