18.8.1.1. Executing Python Signal Handlers
The Python signal handler is not executed in the low-level (C) signal handler. Instead, the low-level signal handler sets a flag that tells the virtual machine to execute the appropriate Python signal handler at a later point (for example, in the following bytecode instruction). This has consequences:
[...]
A long-term calculation implemented exclusively in C (for example, matching regular expressions in a large text) can work without interruption for an arbitrary period of time, regardless of the received signals. Python signal handlers will be called when the calculation completes.
The Qt event loop is implemented in C (++). This means that while it is running and Python code is not being called (for example, using a Qt signal connected to the Python slot), signals are marked, but Python signal handlers are not called.
But , since Python 2.6 and in Python 3, you can force Qt to run the Python function when the signal with the handler is received using signal.set_wakeup_fd() .
This is possible because, unlike the documentation, the low-level signal handler not only sets a flag for the virtual machine, but can also write a byte to the file descriptor set by set_wakeup_fd() . Python 2 writes a null byte, Python 3 writes a signal number.
So, subclassing the Qt class, which takes a file descriptor and provides a readReady() signal, for example, for example. QAbstractSocket , the event loop will execute a Python function every time a signal is received (with a handler), forcing the signal handler to execute instantly without the need for timers:
import sys, signal, socket from PyQt4 import QtCore, QtNetwork class SignalWakeupHandler(QtNetwork.QAbstractSocket): def __init__(self, parent=None): super().__init__(QtNetwork.QAbstractSocket.UdpSocket, parent) self.old_fd = None
cg909 May 14 '16 at 16:42 2016-05-14 16:42
source share