Python + Qt : pyqtProperty, 样式表和事件处理程序

标签 python pyqt pyqt4 qtstylesheets

最近,我一直在努力理解 pyqtProperty 的用法。在下面的代码片段中,我尝试创建一个自定义按钮,单击它后会更改它的文本和外观。我想将逻辑和外观分开,所以我创建了自定义属性“state”,它在样式表中使用。

结果对我来说有点奇怪。程序抛出 'CustomButton' object has no attribute '_state' 异常,但仍然运行。单击按钮后,按钮的文本会发生变化,但颜色保持不变。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys
from PyQt4 import QtGui, QtCore

STYLE = '''
CustomButton {
    margin: 50px;
    padding: 10px;
}
CustomButton[state='true'] {
    background: yellowgreen;
}
CustomButton[state='false'] {
    background: orangered;
}
'''


class CustomButton(QtGui.QPushButton):
    def __init__(self):
        super(CustomButton, self).__init__()
        self.setText('ON')
        self.setStyleSheet(STYLE)
        self._state = True

    def g_state(self):
        return self._state

    def s_state(self, value):
        self._state = value

    state = QtCore.pyqtProperty(bool, fget=g_state, fset=s_state)

    def mousePressEvent(self, event):
        print 'clicked'
        if self.state == True:
            self.state = False
            self.setText('OFF')
        else:
            self.state = True
            self.setText('ON')


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    b = CustomButton()
    b.show()
    sys.exit(app.exec_())

最佳答案

这里有几个问题。

首先,重新实现的 mousePressEvent 应该调用基类实现以保持正常行为。

其次,对属性的更改不会自动触发样式更改,因此您需要在代码中明确地执行此操作。

此外,值得注意的是,pyqtProperty 可以用作装饰器,这可能会稍微提高代码的可读性。

因此,经过这些更改,代码可能看起来像这样:

    ...

    @QtCore.pyqtProperty(bool)
    def state(self):
        return self._state

    @state.setter
    def state(self, value):
        self._state = value

    def mousePressEvent(self, event):
        print 'clicked'
        if self.state:
            self.state = False
            self.setText('OFF')
        else:
            self.state = True
            self.setText('ON')
        self.style().unpolish(self)
        self.style().polish(self)
        self.update()
        super(CustomButton, self).mousePressEvent(event)

关于Python + Qt : pyqtProperty, 样式表和事件处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21068557/

相关文章:

pyqt4 - 如何在 PyQt4 中为 QListView 获取 selectionchange 事件

python - PyQt4 Qtreewidget - 如果选中子复选框,则获取层次结构文本

python - 在 Jinja2 中,将所有键设置为字典的值的最简单方法是什么?

python - 打印输出python子进程

c# - 从 C# 调用 python 函数

python - 灰度图像颜色表

python - SciPy 模块错误 w = np.zeros(M) TypeError : 'float' object cannot be interpreted as an integer

python - 使用 setflags() 添加几个复选框到 QListWidgetItem

python - 为什么运行 pybind11 c++ lib 的 pyqt5 QThread 仍然挂起我的主 GUI?

python - 如何干净地关闭 PyQt 应用程序