python - Qt 动态属性 - 如果不是父级,则适用于小部件?
问题描述
我正在尝试在普通 QWidget 上实现按钮行为,并尝试使用它setProperty()
来动态更改样式表中的值。当我使用它的方法显示小部件时,它似乎工作得很好,show()
但是一旦它是父级它就不再工作了,我不明白发生了什么?(不,我不想从 QPushButton 继承,小部件会有很大不同,谢谢。)
有一个例子:
from PySide2 import QtCore, QtGui, QtWidgets
class Example(QtWidgets.QWidget):
STYLESHEET = \
"""
QWidget[pressed=true]
{
background-color: yellow;
}
QWidget[pressed=false]
{
background-color: red;
}
"""
pressed = QtCore.Signal()
def __init__(self, parent=None):
super(Example, self).__init__(parent=parent)
self._buildUi()
self.setStyleSheet(self.STYLESHEET)
self.setProperty('pressed', False)
def _buildUi(self):
self.layout = QtWidgets.QVBoxLayout(self)
self.label = QtWidgets.QLabel('toto')
self.layout.addWidget(self.label)
def mousePressEvent(self, e):
self.pressed.emit()
self.setProperty('pressed', True)
self.setStyle(self.style())
super(Example, self).mousePressEvent(e)
def mouseReleaseEvent(self, e):
self.setProperty('pressed', False)
self.setStyle(self.style())
super(Example, self).mouseReleaseEvent(e)
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
self.mainLayout = QtWidgets.QVBoxLayout(self)
self.test = Example(self)
self.mainLayout.addWidget(self.test)
if __name__ == '__main__':
# w = Example() # Work
w = Window() # Don't Work
w.show()
如果您在if __name__ == '__main__':
条件中切换注释行,您将能够看到同一个小部件的两个结果。
我试过了:
- 从父级调用小部件 mousePressEvent 和 mouseReleaseEvent(只是为了测试) - 不工作
- 手动向 QApplication 发送 StyleChange 事件 - 不工作
- 手动取消抛光/抛光 - 不工作
- 再次设置样式表 - 不要工作
- 从 QPushButton 继承 - 工作,但不是我想要的(我需要了解如何使其工作,而不是使用已经存在的属性。)
PS:我在 Autodesk Maya 中运行此代码,因此 QApplication 实例已经存在,因为它是 Maya 本身。
你们知道发生了什么吗?
解决方案
独立小部件之所以有效,是因为 Qt仅对顶层窗口使用基本样式表属性(背景和边框) ,假设顶层窗口与样式表中指定的类相同。
当 QWidget 有父对象时,它不会自行绘制任何内容。
正如文档所解释的:
如果您从 QWidget 子类化,则需要为您的自定义 QWidget 提供一个paintEvent
因此,在 PyQt/PySide 术语中:
class Example(QtWidgets.QWidget):
# ...
def paintEvent(self, event):
opt = QtWidgets.QStyleOption()
opt.initFrom(self)
qp = QtGui.QPainter(self)
self.style().drawPrimitive(
QtWidgets.QStyle.PE_Widget, opt, qp, self)
推荐阅读
- python - 多维numpy数组中指定范围内的列匹配
- django - 属性错误“QueryDict”对象没有属性“_meta”
- r - 在knitr R Markdown中确定图形和绘图的确切位置
- angular - NativeScript - 单元测试 HttpInterceptor NSLocationStrategy 错误
- identityserver4 - Identity Server 4 和 User.Claims.Properties.Count 在客户端上始终为 0
- java - MongoDB Java驱动程序@BsonDiscriminator不工作
- python - 将 div 类中的信息提取到 json 对象(或数据框)
- pandas - Pandas - 动态地将变量传递给列名
- angular - Mat Table Angular 只有最后一个数据是从数组中打印出来的,每行中的每个字母也是如此
- node.js - 如何限制 node.js 中的流长度