我正在尝试在 UI 代码块和仅用于处理事件响应的单独 python 类之间设置 pyqt 信号。我不想让 UI 代码访问处理程序(经典 MVC 风格)。不幸的是,我很难将插槽连接到信号。这是代码:
from PyQt5 import QtCore
from PyQt5.QtCore import QObject
class UiClass(QObject):
mySignal = QtCore.pyqtSignal( str )
def __init__(self):
QObject.__init__(self)
def send_signal(self):
self.mySignal.emit("Hello world!")
class HandlerClass():
currentMessage = "none"
def register(self, mySignal):
mySignal.connect(self.receive_signal)
@QtCore.pyqtSlot(str)
def receive_signal(self, message):
self.currentMessage = message
print(message)
ui = UiClass()
handler = HandlerClass()
handler.register(ui.mySignal)
ui.send_signal()
当我运行此代码时,它在 handler.register 行失败。错误如下:
回溯(最近一次调用最后一次):
文件“C:\git\IonControl estpyqtslot.py”,第 25 行,位于
handler.register(ui.mySignal)
文件“C:\git\IonControl estpyqtslot.py”,第 17 行,在寄存器中
mySignal.connect(self.receive_signal)
TypeError:UiClass.mySignal[str] 和 receive_signal() 之间的 connect() 失败
我希望这段代码能够成功地将信号注册到插槽,并让处理程序在最后打印“hello world”。我在这里做错了什么?
我的基本问题是:如何将信号连接到属于类的槽函数?
发生错误是因为您在不继承自
pyqtSlot
的类中使用 QObject
装饰器。您可以通过删除装饰器或使 HandlerClass
成为 QObject
的子类来解决问题。
pyqtSlot
的主要目的是允许定义一个槽的多个不同的重载,每个重载都有不同的签名。有时在进行跨线程连接时也可能需要它。然而,这些用例相对较少,并且在大多数 PyQt 应用程序中根本没有必要使用 pyqtSlot
。信号可以连接到任何Python可调用对象,无论它是否被装饰为槽。