问题
Is there any possibility to create signals at runtime when needed?
I'm doing something like this in a function:
class WSBaseConnector(QObject)
def __init__(self) -> None:
super(QObject, self).__init__()
self._orderBookListeners: Dict[str, pyqtSignal[OrderBookData]] = {}
def registerOrderBookListener(self, market: str, listener: Callable[[OrderBookData], None], loop: AbstractEventLoop) -> None:
try:
signal = self._orderBookListeners[market]
except KeyError:
signal = pyqtSignal(OrderBookData)
signal.connect(listener)
self._orderBookListeners[market] = signal
else:
signal.connect(listener)
As you can see, I have a dict that stores str, pyqtSignal pairs. When I try to connect the signal to the listener I get the error:
'PyQt5.QtCore.pyqtSignal' object has no attribute 'connect'
Is it not possible to create pyqtSignals at runtime without been class vars?
Cheers.
回答1:
No, it is not possible. The pyqtSignal object is a factory function that returns a descriptor, so it must be created when the class statement is executed. To quote from the docs:
New signals should only be defined in sub-classes of QObject. They must be part of the class definition and cannot be dynamically added as class attributes after the class has been defined.
New signals defined in this way will be automatically added to the class’s QMetaObject. This means that they will appear in Qt Designer and can be introspected using the QMetaObject API. [emphasis added]
Your code is creating unbound signal objects, which is why you get the attribute error. The distinction between bound and unbound signals is exactly the same as with the methods of classes. To quote again from the docs:
A signal (specifically an unbound signal) is a class attribute. When a signal is referenced as an attribute of an instance of the class then PyQt5 automatically binds the instance to the signal in order to create a bound signal. This is the same mechanism that Python itself uses to create bound methods from class functions.
来源:https://stackoverflow.com/questions/50294652/how-to-create-pyqtsignals-dynamically