在裝飾有不同裝飾器的函數前面使用QtCore.pyqtSlot裝飾器有一個奇怪的問題。下面的問題證明了這個問題。它用一個按鈕實例化一個簡約的Qt程序。在按下按鈕時,發生以下情況:(1)信號'signal_A'和'signal_B'分別連接到實例method_A和method_B。 (2)發出signal_A和signal_B信號。在另一個裝飾器之前使用PyQt4的'pyqtSlot'裝飾器的奇怪行爲
(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)
謝謝,這非常有用。我仍然有點困惑,爲什麼我在程序的不同運行中觀察到不同的行爲。你有什麼主意嗎? – reddish 2014-10-17 19:11:13
@reddish。我不知道。我無法重現那種行爲 - 對我而言,無論如何總是調用'method_B'。真的有關係嗎? – ekhumoro 2014-10-17 19:32:52