举个例子。
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]
那我就可以简单地捕获最后一个参数了。但是,我一直没有确定如何形成槽位签名。
更新一下。
我可能已经回答了我自己的问题,使用 lambda
s:
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的解决方案是首选,因为它允许更灵活的信号数量越大。
你必须通过几个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()