我希望一个对象可以使用多个回调,但是在对象中定义 any 后继回调将覆盖所有先前的回调。但是,回调是经过修饰的,似乎有些混乱。我应该如何定义对象级别的回调,以便可以在其中使用self?
在以下示例中,您可以在使用Python 3.x和PyQt5.11.x的任何计算机上运行该示例程序,该Spinbox最多连接两个valueChanged回调。它们分别称为A
和C
。但是,第二个回调C
永远不会触发,而第三个回调D
会触发。 D
不应触发。
回调函数将打印其字母和旋转框值,因此旋转旋转框时的预期输出为:
got A 1
got C 1
但是,实际输出是:
got A 1
got D 1
这是错误的,因为Spinbox已连接到
callbackA
self.callbackC
我不知道为什么要调用D,因为我实际上没有在任何地方引用它。但是,如果我们从C或D中删除任何装饰器,它们将再次起作用。我在做什么错了?
有问题的代码是:
from PyQt5 import QtWidgets
from PyQt5.QtCore import pyqtSlot
def silenceCallbacks(*elements):
"""Silence events for the duration of a callback. Mostly skipped for this reproduction."""
def silenceCallbacksOf(callback):
def silencedCallback(self, *args, **kwargs):
callback(self, *args, **kwargs)
return silencedCallback
return silenceCallbacksOf
@pyqtSlot(int)
@silenceCallbacks()
def callbackA(px: int):
#correctly called
print('got A', px)
@pyqtSlot(int) #this overwrites the last three functions
@silenceCallbacks()
def callbackB(px: int):
#correctly not called
print('got B', px)
class RecordingSettings(QtWidgets.QDialog):
@pyqtSlot(int)
@silenceCallbacks()
def callbackC(self, px: int):
#incorrectly not called
print('got C', px)
@pyqtSlot(int) #this overwrites the previous pyqtSlot-decorated function
@silenceCallbacks()
def callbackD(self, px: int):
#incorrectly called
print('got D', px)
def __init__(self, window):
super().__init__()
spin = QtWidgets.QSpinBox()
spin.valueChanged.connect(callbackA)
spin.valueChanged.connect(self.callbackC)
layout = QtWidgets.QVBoxLayout()
layout.addWidget(spin)
self.setLayout(layout)
self.show()
app = QtWidgets.QApplication([])
recSettingsWindow = RecordingSettings(app)
recSettingsWindow.show()
app.exec_()