Python: QtGui.QProgressBar 颜色

2 投票
2 回答
8047 浏览
提问于 2025-04-17 21:49

我在想有没有办法自定义进度条的颜色(QtGui.QProgressBar)。比如说,当进度条达到100%时,我们想把它变成绿色。

下面是一个可以运行的例子:

import sys, time
from PyQt4 import QtCore, QtGui

class PbWidget(QtGui.QProgressBar):
    def __init__(self, parent=None, total=20):
        super(PbWidget, self).__init__()
        self.setMinimum(1)
        self.setMaximum(total)        
        self._active = False  

    def update_bar(self, to_add_number):
        while True:
            time.sleep(0.01)
            value = self.value() + to_add_number            
            self.setValue(value)
            QtGui.qApp.processEvents()
            if (not self._active or value >= self.maximum()):                
                break
        self._active = False

    def closeEvent(self, event):
        self._active = False


class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.main_layout = QtGui.QVBoxLayout()

        self.pb=PbWidget(total=101)
        self.main_layout.addWidget(self.pb)

        ok_button = QtGui.QPushButton("Press to update Progress Bar")
        ok_button.clicked.connect(self.OK)      
        self.main_layout.addWidget(ok_button)       

        central_widget = QtGui.QWidget()
        central_widget.setLayout(self.main_layout)
        self.setCentralWidget(central_widget)

    def OK(self):
        self.pb.update_bar(10)

if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    window = MainWindow()
    window.resize(480, 320)
    window.show()
    sys.exit(app.exec_())

2 个回答

2

下面是到目前为止讨论内容的总结。

看起来,控制Qt小部件最简单和灵活的方法就是使用CSS,这在网页开发者中是非常常见的。CSS的语法几乎是自解释的,容易理解(但不容易记住)。在Python/PyQt中使用CSS更简单。你可以在.py脚本中定义CSS样式,或者把它存储为一个单独的myStyle.css文件在磁盘上——这样你就需要用open(path, 'r')来读取它,并且要确保这个文件一直在。

下面是一个例子,展示了如何用CSS来控制一些小部件的外观(对话框、按钮和进度条)(当进度条达到51%时,它会变成红色,这是根据RM的建议)。

在这里输入图片描述


import time
from PyQt4 import QtCore, QtGui

styleData="""
QWidget
{
    color: #b1b1b1;
    background-color: #323232;
}
QProgressBar
{
    border: 2px solid grey;
    border-radius: 5px;
    text-align: center;
}
QProgressBar::chunk
{
    background-color: #d7801a;
    width: 2.15px;
    margin: 0.5px;
}
QPushButton:pressed
{
    background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2d2d2d, stop: 0.1 #2b2b2b, stop: 0.5 #292929, stop: 0.9 #282828, stop: 1 #252525);
}
QComboBox:hover,QPushButton:hover
{
    border: 2px solid QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a);
}
QPushButton
{
    color: #b1b1b1;
    background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #565656, stop: 0.1 #525252, stop: 0.5 #4e4e4e, stop: 0.9 #4a4a4a, stop: 1 #464646);
    border-width: 1px;
    border-color: #1e1e1e;
    border-style: solid;
    border-radius: 6;
    padding: 3px;
    font-size: 12px;
    padding-left: 5px;
    padding-right: 5px;
}"""

class PbWidget(QtGui.QProgressBar):
    def __init__(self, parent=None, total=20):
        super(PbWidget, self).__init__()
        self.setMinimum(1)
        self.setMaximum(total)        
        self._active = False  

    def update_bar(self, to_add_number):
        while True:
            time.sleep(0.01)
            value = self.value() + to_add_number            
            self.setValue(value)
            if value > 50:
                self.change_color("green")
            QtGui.qApp.processEvents()
            if (not self._active or value >= self.maximum()):                
                break
        self._active = False

    def closeEvent(self, event):
        self._active = False

    def change_color(self, color):
        template_css = """QProgressBar::chunk { background: %s; }"""
        css = template_css % color
        self.setStyleSheet(css)

class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.main_layout = QtGui.QVBoxLayout()

        self.pb=PbWidget(total=101)
        self.main_layout.addWidget(self.pb)

        ok_button = QtGui.QPushButton("Press to update Progress Bar")
        ok_button.clicked.connect(self.OK)      
        self.main_layout.addWidget(ok_button)       

        central_widget = QtGui.QWidget()
        central_widget.setLayout(self.main_layout)
        self.setCentralWidget(central_widget)

    def OK(self):
        self.pb.update_bar(10)

if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)

    window = MainWindow()
    window.resize(480, 320)
    window.setStyleSheet(styleData)  
    window.show()
    sys.exit(app.exec_())
4

没错,使用 CSS 就可以做到这一点。没看错,就是 CSS!;)

把这个功能加到你的 PbWidget 类里面:

def change_color(self, color):
    template_css = """QProgressBar::chunk { background: %s; }"""
    css = template_css % color
    self.setStyleSheet(css)

颜色参数可以是像 "yellow"(黄色)、"blue"(蓝色)、"red"(红色)这样的词,也可以用十六进制表示法,比如 "#FFD45" 等等。

你可以在 update_bar 里面调用这个功能,并根据进度条的值传入不同的颜色。例如:

def update_bar(self, to_add_number):
    while True:
        time.sleep(0.5)
        value = self.value() + to_add_number            
        self.setValue(value)
        if value > 50:
            self.change_color("yellow")
        QtGui.qApp.processEvents()
        if (value >= self.maximum()):                
            break
    self._active = False

如果想要改变其他的视觉属性,可以去看看这个链接:Qt 样式表参考,找找 QtProgressBar。祝你好运!!!

撰写回答