【问题标题】:Does changing widget stylesheets using properties work in Qt6 (it did in Qt5)?使用属性更改小部件样式表在 Qt6 中是否有效(在 Qt5 中有效)?
【发布时间】:2021-12-31 23:54:13
【问题描述】:

我想知道这里是否缺少一些东西。我在 Qt5 中使用属性来修改我的一些小部件样式,但它似乎在 Qt6 中不起作用。如果这是一个错误,我会在其他地方报告它,但我只是想知道我是否做错了什么。

我在下面有一个简单的例子,当 qt=5 时,属性更改成功触发样式更改,但在 qt=6 时不会。颜色应该随着数字的增加而改变。任何帮助表示赞赏!

Qt5 工作

Qt6 不工作

qt = 6

if qt == 6:
    from PyQt6.QtGui import QFont
    from PyQt6.QtWidgets import QApplication, QLabel, QWidget, QVBoxLayout
    from PyQt6.QtCore import QTimer
elif qt == 5:
    from PyQt5.QtGui import QFont
    from PyQt5.QtWidgets import QApplication, QLabel, QWidget, QVBoxLayout
    from PyQt5.QtCore import QTimer

import sys


class SampleWidget(QWidget):
    def __init__(self):
        super().__init__()

        self.timer1, self.timer2, self.timer3 = QTimer(), QTimer(), QTimer()
        self.timer1.singleShot(1000, self.fun1)
        self.timer2.singleShot(2000, self.fun2)
        self.timer3.singleShot(3000, self.close)  # noqa

        self.label = QLabel('0')
        font = QFont()
        font.setPointSize(50)
        self.label.setFont(font)
        self.layout = QVBoxLayout(self)
        self.layout.addWidget(self.label)
        self.setLayout(self.layout)

    def fun1(self):
        self.label.setText('1')
        self.set_property(True)

    def fun2(self):
        self.label.setText('2')
        self.set_property(False)

    def set_property(self, style_red):
        self.label.setProperty('StyleRed', style_red)
        self.label.style().unpolish(self.label)
        self.label.style().polish(self.label)
        self.label.update()
        QApplication.processEvents()


app = QApplication([])
app.setStyleSheet('QLabel[StyleRed=true]{color:red;} QLabel[StyleRed=false]{color:green;}')
gui = SampleWidget()
gui.show()
sys.exit(app.exec())

【问题讨论】:

    标签: python pyqt pyqt5 pyqt6


    【解决方案1】:

    从 Qt5 到 6 的行为略有变化,但在这两种情况下,文档已经建议 the solution

    警告:如果在设置样式表后 Qt 属性的值发生了变化,则可能需要强制重新计算样式表。实现此目的的一种方法是取消设置样式表并重新设置。

    顺便说一句,这也是在 Qt5 中实现此目的的正确方法,因为它确保样式表被正确地 [重新] 传播到子小部件,并且无论如何都会自动导致重新抛光。

    由于样式表是级联的,因此无法自动知道样式更改的来源。

    在你的情况下,这就足够了:

        def set_property(self, style_red):
            self.label.setProperty('StyleRed', style_red)
            app.setStyleSheet(app.styleSheet())
    

    但是,如果您想避免完善整个应用程序(这需要一些时间和资源),您可以临时设置另一个样式表并恢复以前的样式表,这对于以下小部件有效可能有也可能没有任何样式表集:

        def set_property(self, style_red):
            self.label.setProperty('StyleRed', style_red)
            old = self.label.styleSheet()
            if not old:
                self.label.setStyleSheet('* {}')
            self.label.setStyleSheet(old)
    

    注意:

    • singleShot 是一个静态函数,不需要为这些计时器创建引用,因为您实际上并没有使用它们;只需使用QTimer.singleShot(1000, self.fun1)等;
    • 选择器的属性值应始终使用引号;它们适用于单个单词的值,但最好始终使用它们;

    【讨论】:

      猜你喜欢
      • 2016-04-30
      • 2015-08-07
      • 1970-01-01
      • 2020-11-08
      • 1970-01-01
      • 2017-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多