Les signaux et les slots¶
Qt introduit le principe de la communication à partir de signaux et de slots. Cela permet de gérer des relations entre des objets avec un couplage faible. De plus, Qt gère de manière transparente la communication directe ou à travers une file de messages (message queue) qui peut servir pour la communication inter threads lorsque des objets ont été créés dans des threads séparés.
Les signaux¶
Tous les objets qui héritent de QObject peuvent émettre des signaux. Un signal
est représenté par une instance de la classe Signal
. Un signal possède une méthode
emit()
qui prend en paramètre une valeur qui peut être transmise avec le signal.
La valeur peut être n’importe quel type Python mais ce dernier doit être précisé
lors de la création du signal.
from PySide2.QtCore import QObject, Signal
class Alarme(QObject):
sonnerie = Signal()
message = Signal(str)
def declencher(self):
self.sonnerie.emit()
self.message.emit("L'alarme se déclenche")
Dans l’exemple ci-dessus, on déclare deux signaux possibles pour la classe
Alarme
. La méthode declencher
émet les deux signaux.
Les slots¶
Les slots sont des méthodes qui pourront être connectées à un signal de manière
à être appelées lors de l’émission du signal. Un slot doit accepter en paramètre
le même type de données que celui émis par un signal. On utilise le décorateur
@Slot
pour déclarer un slot. On précise au décorateur le type du paramètre.
from PySide2.QtCore import Slot
class Sirene:
@Slot()
def sonner(self):
print("faire du bruit")
from PySide2.QtCore import Slot
class Messagerie:
@Slot(str)
def envoyer(self, message):
print(f"envoyer le message '{message}'")
Connecter les signaux et les slots¶
L’intérêt principal des signaux et des slots est de permettre un couplage
faible entre les classes en connectant a posteriori les signaux à des slots
grâce à la méthode connect
qui prend en paramètre le slot à connecter.
alarme = Alarme()
sirene = Sirene()
messagerie = Messagerie()
alarme.sonnerie.connect(sirene.sonner)
alarme.message.connect(messagerie.envoyer)
alarme.declencher()
# Affiche
# faire du bruit
# envoyer le message 'L'alarme se déclenche'
Note
Un signal peut émettre plusieurs valeurs et, symétriquement, un slot peut accepter plusieurs paramètres. Dans ce cas, il faut déclarer le type de chaque paramètre.