使用属性更改小部件样式表在 Qt6 中有效吗(它在 Qt5 中有效)?
Does changing widget stylesheets using properties work in Qt6 (it did in Qt5)?
我想知道我是否遗漏了什么。我在Qt5中用properties修改了我的一些widget样式,但是在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())
行为从 Qt5 到 6 略有变化,但在这两种情况下,文档都已经建议 the solution:
Warning: If the value of the Qt property changes after the style sheet has been set, it might be necessary to force a style sheet recomputation. One way to achieve this is to unset the style sheet and set it again.
顺便说一句,这也是在 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)
,等等;
- 属性 选择器的值应始终使用引号;它们适用于单个单词值,但无论如何始终使用它们是一种很好的做法;
我想知道我是否遗漏了什么。我在Qt5中用properties修改了我的一些widget样式,但是在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())
行为从 Qt5 到 6 略有变化,但在这两种情况下,文档都已经建议 the solution:
Warning: If the value of the Qt property changes after the style sheet has been set, it might be necessary to force a style sheet recomputation. One way to achieve this is to unset the style sheet and set it again.
顺便说一句,这也是在 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)
,等等;- 属性 选择器的值应始终使用引号;它们适用于单个单词值,但无论如何始终使用它们是一种很好的做法;