【发布时间】:2014-10-17 15:28:03
【问题描述】:
在使用不同装饰器装饰的函数前面使用 QtCore.pyqtSlot 装饰器时,我遇到了一个奇怪的问题。下面的问题演示了这个问题。它用一个按钮实例化一个简约的 Qt 程序。按下按钮时,会发生以下情况:
(1) 信号“signal_A”和“signal_B”分别连接到实例 method_A 和 method_B。
(2) signal_A 和 signal_B 信号被发射。
(3) 预期的行为是method_A和method_B被执行。然而,事实证明,signal_A 和 signal_B 都触发了 method_A 或 method_B(奇怪的是,这是不确定的,并且每次运行程序都不同!)。
这似乎是一个错误。
使用 PyQt4 绑定到 Qt 时会出现此问题。使用 PySide 时不存在(使用“--pyside”参数进行验证)。我在 Python 2 和 3 以及 Windows 和 Linux 中都看到了这个问题。
问题似乎与在“@QtSlot”和方法定义之间插入装饰器有关。测试程序中的“null_decorator”应该什么都不做(如果我对装饰器的理解是正确的),但是当我删除它时程序的行为会发生变化。
任何帮助理解这里发生的事情将不胜感激。
#! /usr/bin/env python3
import sys, time
if "--pyside" not in sys.argv:
# default to PyQt4 bindings
from PyQt4 import QtCore, QtGui
QtSignal = QtCore.pyqtSignal
QtSlot = QtCore.pyqtSlot
else:
# alternatively, use PySide bindings
from PySide import QtCore, QtGui
QtSignal = QtCore.Signal
QtSlot = QtCore.Slot
def null_decorator(f):
def null_decorator_wrapper(self, *args, **kwargs):
return f(self, *args, **kwargs)
return null_decorator_wrapper
class TestClass(QtCore.QObject):
def __init__(self, *args, **kwargs):
super(TestClass, self).__init__(*args, **kwargs)
@QtSlot()
@null_decorator
def method_A(self):
print("method_A() executing!")
@QtSlot()
@null_decorator
def method_B(self):
print("method_B() executing!")
class DemonstrateProblemButton(QtGui.QPushButton):
signal_A = QtSignal()
signal_B = QtSignal()
def __init__(self, *args, **kwargs):
super(DemonstrateProblemButton, self).__init__(*args, **kwargs)
self.clicked.connect(self.on_clicked)
@QtSlot()
def on_clicked(self):
# Create TestClass instance
instance = TestClass()
# connect the signals
self.signal_A.connect(instance.method_A)
self.signal_B.connect(instance.method_B)
# emit the signals
self.signal_A.emit()
self.signal_B.emit()
def main():
# instantiate the GUI application
app = QtGui.QApplication(sys.argv)
button = DemonstrateProblemButton("Demonstrate Problem")
button.show()
return QtGui.QApplication.exec_()
if __name__ == "__main__":
exitcode = main()
sys.exit(exitcode)
【问题讨论】:
标签: python qt pyqt4 decorator signals-slots