如何将多个PyQt信号和变量参数连接到一个slotsignal中继器上?

问题描述 投票:0回答:1

举个例子。

class MyClass(QObject):
    signal_1 = pyqtSignal(str, int)
    signal_2 = pyqtSignal(int, int)
    signal_3 = pyqtSignal(str, int, int)

假设每个信号都连接到其他地方来执行不同的功能 然而,我希望在执行一个特定的功能的时候 任何 的信号发出。这种无差别函数所做的事情只关心,比如说,最后的 int 与信号一起发出的参数。槽子表面上会是这样的。

class OtherClass(QObject):

    ...

    @pyqtSlot(int)
    def unifiedResponse(self, index):
        # Here I would do something with that index

有没有办法把任意数量的信号和任意参数直接连接到槽上 或者连接到中继器信号上?

如果有一种方法可以这样定义一个槽。

@pyqtSlot(???)
def unifiedResponse(self, *args):
    important_var = args[-1]

那我就可以简单地捕获最后一个参数了。但是,我一直没有确定如何形成槽位签名。

更新一下。

我可能已经回答了我自己的问题,使用 lambdas:

signal_1.connect(lambda _, source: OtherClass.unifiedResponse(source))
signal_2.connect(lambda _, source: OtherClass.unifiedResponse(source))
signal_3.connect(lambda _, _, source: OtherClass.unifiedResponse(source))

然而,下面@eyllanesc的解决方案是首选,因为它允许更灵活的信号数量越大。

python pyqt qt-signals
1个回答
2
投票

你必须通过几个pyqtSlot来设置所有信号的签名。

from PyQt5.QtCore import pyqtSignal, pyqtSlot, QCoreApplication, QObject, QTimer


class MyClass(QObject):
    signal_1 = pyqtSignal(str, int)
    signal_2 = pyqtSignal(int, int)
    signal_3 = pyqtSignal(str, int, int)


class OtherClass(QObject):
    @pyqtSlot(str, int)
    @pyqtSlot(int, int)
    @pyqtSlot(str, int, int)
    def unifiedResponse(self, *args):
        print(args)


def main():
    import sys

    app = QCoreApplication(sys.argv)

    sender = MyClass()
    receiver = OtherClass()

    sender.signal_1.connect(receiver.unifiedResponse)
    sender.signal_2.connect(receiver.unifiedResponse)
    sender.signal_3.connect(receiver.unifiedResponse)

    def on_timeout():
        sender.signal_1.emit("StackOverflow", 1)
        sender.signal_2.emit(1, 2)
        sender.signal_3.emit("StackOverflow", 1, 2)

        QTimer.singleShot(1000, QCoreApplication.quit)

    QTimer.singleShot(1000, on_timeout)

    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

如果在一般情况下,你想发送几种类型的数据,那么最好使用一个更通用的数据类型,比如一个列表(或一个对象)。

class MyClass(QObject):
    signal_1 = pyqtSignal(list)
    signal_2 = pyqtSignal(list)
    signal_3 = pyqtSignal(list)


class OtherClass(QObject):
    @pyqtSlot(list)
    def unifiedResponse(self, args):
        print(args)


def main():
    import sys

    app = QCoreApplication(sys.argv)

    sender = MyClass()
    receiver = OtherClass()

    sender.signal_1.connect(receiver.unifiedResponse)
    sender.signal_2.connect(receiver.unifiedResponse)
    sender.signal_3.connect(receiver.unifiedResponse)

    def on_timeout():
        sender.signal_1.emit(["StackOverflow", 1])
        sender.signal_2.emit([1, 2])
        sender.signal_3.emit(["StackOverflow", 1, 2])

        QTimer.singleShot(1000, QCoreApplication.quit)

    QTimer.singleShot(1000, on_timeout)

    sys.exit(app.exec_())

更新。

没有一个优雅的方法来访问最后一个元素,但第一个元素,因为插槽签名必须是信号签名的子集,例如,签名为 "int "的插槽可以接受具有第一个类型为 "int "的签名的信号,其他参数被丢弃。

from PyQt5.QtCore import pyqtSignal, pyqtSlot, QCoreApplication, QObject, QTimer


class MyClass(QObject):
    signal_1 = pyqtSignal(int, str)
    signal_2 = pyqtSignal(int, int)
    signal_3 = pyqtSignal(int, str, int)


class OtherClass(QObject):
    @pyqtSlot(int)
    def unifiedResponse(self, index):
        print(index)


def main():
    import sys

    app = QCoreApplication(sys.argv)

    sender = MyClass()
    receiver = OtherClass()

    sender.signal_1.connect(receiver.unifiedResponse)
    sender.signal_2.connect(receiver.unifiedResponse)
    sender.signal_3.connect(receiver.unifiedResponse)

    def on_timeout():
        sender.signal_1.emit(1, "StackOverflow")
        sender.signal_2.emit(2, 2)
        sender.signal_3.emit(3, "StackOverflow", 1)

        QTimer.singleShot(1000, QCoreApplication.quit)

    QTimer.singleShot(1000, on_timeout)

    sys.exit(app.exec_())


if __name__ == "__main__":
    main()
© www.soinside.com 2019 - 2024. All rights reserved.