I'm trying to set up a pyqt signal between a block of UI code and a separate python class that is just for handling event responses. I don't want to give the UI code access to the handler (classic MVC style). Unfortunately, I am having difficulty connecting the slot to the signal. Here is the code:
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()
When I run this code it fails at the handler.register line. Here is the error:
Traceback (most recent call last):
File "C:\git\IonControl\testpyqtslot.py", line 25, in
handler.register(ui.mySignal)
File "C:\git\IonControl\testpyqtslot.py", line 17, in register
mySignal.connect(self.receive_signal)
TypeError: connect() failed between UiClass.mySignal[str] and receive_signal()
I'd like this code to successfully register the signal to the slot and have the handler print "hello world" at the end. What did I do wrong here?
My basic question is this: how do I connect a signal to a slot function that is part of a class?
The error happens becuase you are using pyqtSlot
decorator in a class which doesn't inherit from QObject
. You can fix the problem by either getting rid of the decorator, or making HandlerClass
a subclass of QObject
.
The main purpose of pyqtSlot
is to allow several different overloads of a slot to be defined, each with a different signature. It may also be needed sometimes when making cross-thread connections. However, these use-cases are relatively rare, and in most PyQt applications it is not necessary to use pyqtSlot
at all. Signals can be connected to any python callable object, whether it is decorated as a slot or not.