进度栏颜色

时间:2015-07-02 09:32:17

标签: c++ css qt

我需要QProgressBar更改特定值的颜色,例如

  • 0-60 Int部分:绿色
  • 60-80 Int:Orange
  • 80-100 Int:Red

但我无法找到解决方案。从样式表中,进度条的整个颜色在值上更改,但不是部分更改。

我使用基于QT creator 3.4.0的{​​{1}}。

6 个答案:

答案 0 :(得分:3)

你可以使用这样的样式表来实现:

QProgressBar* bar = new QProgressBar();
bar->setStyleSheet("::chunk {"
                   "background-color: "
                   "qlineargradient(x0: 0, x2: 1, "
                   "stop: 0 green, stop: 0.6 green, "
                   "stop: 0.60001 orange, stop: 0.8 orange, "
                   "stop: 0.80001 red, stop: 1 red"
                   ")}");

看起来像这样:

enter image description here

你可以简单地应用它来使它更顺畅:

 bar->setStyleSheet("::chunk {"
                    "background-color: "
                    "qlineargradient(x0: 0, x2: 1, "
                    "stop: 0 green, stop: 0.6 green, "
                    "stop: 0.8 orange, "
                    "stop: 1 red"
                    ")}");

enter image description here

更新

这个解决方案不正确,因为值小于最大值你会得到这样的结果:

enter image description here

正如其他人所指出的那样:Gradient for chunks in QProgressBar

唯一的解决方案似乎是自定义paintEvent

UPDATE2:

为了完整起见,这里是自定义paintEvent的相关代码。这样可行,但看起来不太好。此外,大多数参数应该是类成员并由用户设置。但是:

<强> coloredprogressbar.h

#ifndef COLOREDPROGRESSBAR_H
#define COLOREDPROGRESSBAR_H

#include <QWidget>
#include <QProgressBar>
#include <QPaintEvent>

class ColoredProgressBar : public QProgressBar
{
    Q_OBJECT
public:
    explicit ColoredProgressBar(QWidget *parent = 0);
    ~ColoredProgressBar();

protected:

    void paintEvent(QPaintEvent*) Q_DECL_OVERRIDE;

signals:

public slots:
};

#endif // COLOREDPROGRESSBAR_H

<强> coloredprogressbar.cpp

#include "coloredprogressbar.h"

#include <QPainter>
#include <QBrush>
#include <QStyle>
#include <QPen>
#include <QColor>

ColoredProgressBar::ColoredProgressBar(QWidget *parent) : QProgressBar(parent)
{

}

ColoredProgressBar::~ColoredProgressBar()
{

}

void ColoredProgressBar::paintEvent(QPaintEvent*)
{
    int val = value();
    int pos = QStyle::sliderPositionFromValue(minimum(), maximum(), val, width());

    int pos60 = QStyle::sliderPositionFromValue(minimum(), maximum(), 60, width());
    int pos80 = QStyle::sliderPositionFromValue(minimum(), maximum(), 80, width());

    QPainter p(this);
    p.setPen(Qt::green);
    p.setBrush(QBrush(Qt::green));

    if(val >= 0 && val <= 60)
    {
        p.drawRect(0,0,pos,height());
    }
    else if(val > 60 && val <= 80)
    {
        p.drawRect(0,0,pos60,height());
        p.setPen(QColor(255,127,0));
        p.setBrush(QBrush(QColor(255,127,0)));
        p.drawRect(pos60, 0, pos - pos60, height());
    }
    else
    {
        p.drawRect(0,0,pos60,height());
        p.setPen(QColor(255,127,0));
        p.setBrush(QBrush(QColor(255,127,0)));
        p.drawRect(pos60, 0, pos80 - pos60,height());
        p.setPen(Qt::red);
        p.setBrush(QBrush(Qt::red));
        p.drawRect(pos80, 0, pos - pos80, height());
    }

    p.setPen(Qt::lightGray);
    p.setBrush(QBrush(Qt::lightGray));
    p.drawRect(pos, 0, width(), height());


    p.setPen(Qt::black);
    p.setBrush(QBrush(Qt::black));
    p.drawText(0,0, width(), height(), Qt::AlignCenter, QString::number(val) + "%");
}

<强>使用

#include <QApplication>
#include "coloredprogressbar.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    ColoredProgressBar bar;
    bar.setValue(85);
    bar.show();

    return a.exec();
}

我再说一遍,这只是一个看起来不错的简单实现,并且错过了一些用户可设置的功能,但可能是一个开始的地方。随意编辑此代码。

答案 1 :(得分:2)

我找到了一个可以使用样式表的解决方案,虽然它不是很灵活。您可以设置QProgressBar的背景而不是块,然后使用倒置的外观:

QProgressBar.setInvertedAppearance(True)

以上命令适用于PyQt5,因此请查看正确的c ++命令。 使用以下样式表,我使用的渐变是垂直进度条,因此需要进行一些调整才能使其水平正确。在这种情况下,也请使用width:代替height:

QProgressBar{
    border: 2px solid grey;
    border-radius: 3px;
    text-align: center;
    background-color: qlineargradient(spread:pad, x1:0.5, y1:1, x2:0.5, y2:0, 
                               stop:0 rgba(0, 170, 0, 255), stop:0.33 rgba(255, 255, 0, 255),
                               stop:0.6 rgba(232, 165, 0, 255), stop:1 rgba(189, 0, 0, 255));
}

QProgressBar::chunk {
    background-color: rgb(50,50,50);
    margin: 0px;
    height: 5px;
}

此限制是您不能使用带边距的块,并且必须反转为进度设置的值。因此100变为0,70变为30等。

通过将块的高度设置为0.5px这样的小值,可以将其用作连续进度条。希望它为一些人省去了继承QProgressBar并实现画家的麻烦!

答案 2 :(得分:0)

使用现有样式表属性无法实现所需。然而,你可以将QProgressBar子类化并重新实现绘画以获得你想要的外观。

答案 3 :(得分:0)

正如@Gabriel de Grimouard已经提到的那样,你需要继承QProgressBar并重新实现绘画。然而,还有另一种方法(可能有点脏,但很快) - 子类QProgressBar并修改setValue槽。

QString style_0_60      = "QProgressBar::chunk{ background-color: green; }";
QString style_60_80     = "QProgressBar::chunk{ background-color: orange; }";
QString style_80_100    = "QProgressBar::chunk{ background-color: red; }";

#include <QProgressBar>

class MyProgressBar : public QProgressBar
{
public:
    MyProgressBar();
    void    setValue(int value);
};

void MyProgressBar::setValue(int value)
{
    if(value >= 0 && value < 60)
        this->setStyleSheet(style_0_60);
    else if (value >= 60 && value < 80)
        this->setStyleSheet(style_60_80);
    else
        this->setStyleSheet(style_80_100);

    QProgressBar::setValue(value);
}

答案 4 :(得分:0)

我使用了@Miki示例。它给了我很多帮助,但它是纯色的。为了使它成为渐变,我修改了cpp。 由于这是一个关于进度条中多种颜色的好主题,我认为这将是一个很好的贡献。

int val = value();
int pos = QStyle::sliderPositionFromValue(minimum(), maximum(), val, width());

QPainter p(this);

QLinearGradient linearGrad(this->rect().topLeft(), this->rect().bottomRight());
linearGrad.setColorAt(0, Qt::red);
linearGrad.setColorAt(0.2, QColor(255, 165, 0));
linearGrad.setColorAt(1, Qt::green);
QRect rect_linear(this->rect().topLeft(), this->rect().bottomRight());
p.fillRect(rect_linear, linearGrad);

p.setPen(Qt::lightGray);
p.setBrush(QBrush(Qt::lightGray));
p.drawRect(pos, 0, width(), height());

答案 5 :(得分:0)

我觉得可以先画整个渐变条。然后画出我们想要的部分。

enter image description here

代码,部分代码来自@Miki,谢谢@Miki

void ColoredProgressBar::paintEvent(QPaintEvent* e) {
    int val = value();
    int w = width();
    int h = height();
    int pos = QStyle::sliderPositionFromValue(minimum(), maximum(), val, width());

    // Paint on pixmap
    QPixmap pixmap(w, h);
    QPainter pixmapPainter(&pixmap);
    QLinearGradient linearGradient(0, 0, w, h);
    linearGradient.setColorAt(0, Qt::green);
    linearGradient.setColorAt(0.5, Qt::yellow);
    linearGradient.setColorAt(1, Qt::red);

    QBrush pixmapBrush(linearGradient);
    pixmapPainter.setBrush(pixmapBrush);
    pixmapPainter.drawRect(0, 0, width(), height());

    // Paint the progress bar
    QPainter painter(this);
    QBrush brush(pixmap);
    painter.setBrush(brush);
    painter.drawRect(0, 0, pos, height());

    // Paint background
    painter.setPen(Qt::lightGray);
    painter.setBrush(QBrush(Qt::lightGray));
    painter.drawRect(pos, 0, width(), height());

    // Paint text
    painter.setPen(Qt::black);
    painter.setBrush(QBrush(Qt::black));
    painter.drawText(0, 0, width(), height(), Qt::AlignCenter, QString::number(val) + "%");
}