anonymous | 2020-05-11 07:09:23 UTC | #1
Is there any reason why signals of WorkerSignals are class variables?
martin | 2020-09-11 20:41:22 UTC | #2
This is actually due to how PyQt5 (and PySide2) hook up signals and create Qt objects, and how the order of that relates to their related Python objects.
When you define a signal on a class, e.g.
class MyWindow(QMainWindow):
my_custom_signal = pyqtSignal()
You are creating an instance of pyqtSignal
and assigning it to the class variable my_custom_signal
. However, nothing is happening in Qt here, this is just a simple Python object.
When you create an instance of your MyWindow
class the Python object is created, the __init__
is run, the super()
class is called and then PyQt5 creates the Qt objects, and hooks everything together. At this point PyQt5 searches for signal definitions on the object, and hooks these up using Qt signals (with appropriate magic).
Create GUI Applications with Python & Qt6 by Martin Fitzpatrick — (PyQt6 Edition) The hands-on guide to making apps with Python — Over 10,000 copies sold!
If you defined signals in your __init__
like you might expect...
class MyWindow(QMainWindow):
def __init__(self):
super().__init__()
self.my_custom_signal = pyqtSignal()
this won't work.... because when you call the super init, PyQt5 will try and hook up the signals, but you haven't defined them yet.
Of course, PyQt5 could require you have to put the super().__init__
call after you've created the signals....
class MyWindow(QMainWindow):
def __init__(self):
self.my_custom_signal = pyqtSignal()
super().__init__()
...but that's surprising and not very nice.
Putting them on the class side-steps all this.
PyQt/PySide 1:1 Coaching with Martin Fitzpatrick — Get one on one help with your Python GUI projects. Working together with you I'll identify issues and suggest fixes, from bugs and usability to architecture and maintainability.