在valueChanged上调用不同名称的PyQt5回调

时间:2018-08-29 23:56:38

标签: python pyqt pyqt5

我希望一个对象可以使用多个回调,但是在对象中定义 any 后继回调将覆盖所有先前的回调。但是,回调是经过修饰的,似乎有些混乱。我应该如何定义对象级别的回调,以便可以在其中使用self?

在以下示例中,您可以在使用Python 3.x和PyQt5.11.x的任何计算机上运行该示例程序,该Spinbox最多连接两个valueChanged回调。它们分别称为AC。但是,第二个回调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_()

0 个答案:

没有答案