Qt Dynamic Properties - 如果不是只有父级,是否适用于小部件?
Qt Dynamic Properties - Works for widget if not parented only?
我正在尝试在普通 QWidget 上实现按钮行为,并且正在尝试使用 setProperty()
动态更改样式表中的值。
当我使用它的 show()
方法显示小部件时它似乎运行良好,但是一旦它成为父级它就不再起作用了,我不明白发生了什么?? (不,我不想继承QPushButton,widget会有很大不同,谢谢。)
有个例子:
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 事件 - 不起作用
- unpolish/polish 手动 - 不起作用
- 再次设置样式表 - 不行
- 继承自 QPushButton - 工作,但不是我想要的(我需要了解如何使它工作,而不是使用现有的属性。)
PS:
我 运行 此代码在 Autodesk Maya 中,因此 QApplication 实例已经存在,因为它是 Maya 本身。
你们知道发生了什么事吗?
独立小部件可以工作,因为 Qt 使用基本样式表属性(背景和边框)仅用于顶层 windows,假设顶层 window 与样式表中指定的 class 相同。
当 QWidget 有父级时,它不会自己绘制任何东西。
作为 documentation explains:
If you subclass from QWidget, you need to provide a paintEvent for your custom QWidget
因此,在 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)
我正在尝试在普通 QWidget 上实现按钮行为,并且正在尝试使用 setProperty()
动态更改样式表中的值。
当我使用它的 show()
方法显示小部件时它似乎运行良好,但是一旦它成为父级它就不再起作用了,我不明白发生了什么?? (不,我不想继承QPushButton,widget会有很大不同,谢谢。)
有个例子:
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 事件 - 不起作用
- unpolish/polish 手动 - 不起作用
- 再次设置样式表 - 不行
- 继承自 QPushButton - 工作,但不是我想要的(我需要了解如何使它工作,而不是使用现有的属性。)
PS: 我 运行 此代码在 Autodesk Maya 中,因此 QApplication 实例已经存在,因为它是 Maya 本身。
你们知道发生了什么事吗?
独立小部件可以工作,因为 Qt 使用基本样式表属性(背景和边框)仅用于顶层 windows,假设顶层 window 与样式表中指定的 class 相同。
当 QWidget 有父级时,它不会自己绘制任何东西。
作为 documentation explains:
If you subclass from QWidget, you need to provide a paintEvent for your custom QWidget
因此,在 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)