17.4. signal - Définir des gestionnaires d'événements pour les événements asynchrones
Bien que Python les gestionnaires de signaux sont appelés de manière asynchrone autant que le Python utilisateur est concerné, ils ne peuvent se produire entre les "atomique" instructions de l'interpréteur Python. Cela signifie que les signaux arrivant pendant de longs calculs mis en œuvre uniquement en C (comme l'expression régulière correspond sur de grands corps de texte) peut être retardé pour une quantité arbitraire de fois.
Cela signifie que Python ne peut pas traiter les signaux de la boucle d'événement de Qt est en cours d'exécution. Seulement lorsque l'interpréteur Python run (quand le QApplication se ferme, ou lorsqu'une fonction Python est appelée à partir de l'intervalle Qt) le gestionnaire de signal sera appelée.
Une solution est d'utiliser un QTimer de laisser l'interprète de courir de temps à temps.
Notez que, dans le code ci-dessous, si il n'y a pas de fenêtres ouvertes, l'application va se fermer après la boîte de message quel que soit le choix de l'utilisateur en raison de QApplication.quitOnLastWindowClosed() == True. Ce comportement peut être modifié.
import signal
import sys
from PyQt4.QtCore import QTimer
from PyQt4.QtGui import QApplication, QMessageBox
# Your code here
def sigint_handler(*args):
"""Handler for the SIGINT signal."""
sys.stderr.write('\r')
if QMessageBox.question(None, '', "Are you sure you want to quit?",
QMessageBox.Yes | QMessageBox.No,
QMessageBox.No) == QMessageBox.Yes:
QApplication.quit()
if __name__ == "__main__":
signal.signal(signal.SIGINT, sigint_handler)
app = QApplication(sys.argv)
timer = QTimer()
timer.start(500) # You may change this if you wish.
timer.timeout.connect(lambda: None) # Let the interpreter run each 500 ms.
# Your code here.
sys.exit(app.exec_())
Une autre solution possible, comme indiqué par LinearOrbit, est - signal.signal(signal.SIGINT, signal.SIG_DFL)
, mais il n'autorise pas les gestionnaires personnalisés.