Динамическое изменение стилей QProgressBar в PyQt

Рейтинг: 1Ответов: 1Опубликовано: 31.05.2023

Мне нужно изменять стили в зависимости от действий, происходящих в программе. Аналог JS на HTML странице, где можно добавлять, удалять классы из CSS, только в PyQt.

Я пробовал сделать нечто подобное:

if strength < 33:
    self.reliability.setObjectName('rel-0')
elif strength < 66:
    self.reliability.setObjectName('rel-1')
else:
    self.reliability.setObjectName('rel-2')

Предварительно прописав в файле со стилями эти селекторы:

#rel-0, #rel-1, #rel-2 {
    border: 2px solid #453e3e;
    border-radius: 5px;
    text-align: center;
    background-color: #453e3e;
    color: rgba(69, 62, 62, 0);
}

#rel-0::chunk {
    background-color: #ed0909;
}

#rel-1::chunk {
    background-color: #e3c010;
}

#rel-2::chunk {
    background-color: #44d111;
}

Но, судя по всему при изменении ObjectName элементы не обновляют стили, которые присущи этим идентификаторам.

Я также пытался делать repaint() и update(). Но видимо они тоже не "видят" изменение стилей.

PS: Неужели придется делать каждый раз setStylesheet()?

Ответы

▲ 2Принят

Изменение имени объекта - плохая идея, я бы предложил попробовать так:

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt, QTimer


class ProgressBar(QProgressBar):
    def __init__(self):
        super().__init__()
        self.setValue(0)
        self.setMaximum(100)
        
    def updateBar(self):
        value = self.value() + 1
        self.setValue(value)

        if value < 33:
            self.changeColor('red')
        elif value < 66:
            self.changeColor('#de7c09')       
        else:
            self.changeColor('green')

    def changeColor(self, color):
        css = """
            ::chunk {{
                background: {0};
            }}
        """.format(color)
        self.setStyleSheet(css)


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.centralwidget = QWidget(self)
        self.setCentralWidget(self.centralwidget)
        
        self.reliability = ProgressBar()
        
        self.layout = QVBoxLayout(self.centralwidget)
        self.layout.addWidget(self.reliability)
        
        self.timer = QTimer(self, timeout=self.onTimeout)
        self.timer.start(100)
        
    def onTimeout(self):
        self.reliability.updateBar()

        if self.reliability.value() > 100:
            self.timer.stop()


Stylesheet = '''            
QProgressBar {
    border: 2px solid #453e3e;
    border-radius: 5px;
    text-align: center;
    font-size: 20px;
    background-color: #553e3e;
    color: rgba(255, 255, 255, 255);
}
'''    
 
    
if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setStyleSheet(Stylesheet)
    w = MainWindow()
    w.resize(500, 200)
    w.show()
    sys.exit(app.exec_())

введите сюда описание изображения

введите сюда описание изображения

введите сюда описание изображения