我需要QProgressBar
更改特定值的颜色,例如
但我无法找到解决方案。从样式表中,进度条的整个颜色在值上更改,但不是部分更改。
我使用基于QT creator 3.4.0
的{{1}}。
答案 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"
")}");
看起来像这样:
你可以简单地应用它来使它更顺畅:
bar->setStyleSheet("::chunk {"
"background-color: "
"qlineargradient(x0: 0, x2: 1, "
"stop: 0 green, stop: 0.6 green, "
"stop: 0.8 orange, "
"stop: 1 red"
")}");
这个解决方案不正确,因为值小于最大值你会得到这样的结果:
正如其他人所指出的那样:Gradient for chunks in QProgressBar
唯一的解决方案似乎是自定义paintEvent
为了完整起见,这里是自定义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)
我觉得可以先画整个渐变条。然后画出我们想要的部分。
代码,部分代码来自@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) + "%");
}