Les événements en PyQt6
Introduction
Dans ce chapitre, nous allons explorer en détail la gestion des événements dans PyQt. La gestion des événements constitue une pierre angulaire de la programmation d’applications interactives : elle permet d’associer des actions spécifiques effectuées par l’utilisateur (comme un clic de souris, une pression sur une touche, ou encore un déplacement de curseur) à des traitements ou des réactions programmées.
Imaginez par exemple qu’un utilisateur clique sur un bouton dans une interface. Ce clic pourrait entraîner l’affichage d’un message, l’exécution d’un calcul complexe, ou encore le chargement de données à partir d’un fichier ou d’une base de données. Ce mécanisme repose sur une interaction subtile mais essentielle entre deux notions fondamentales en PyQt :
-
Le signal : il représente l’événement émis par un composant ou widget de l’interface (par exemple, le clic sur un bouton ou une modification d’une valeur dans un champ).
-
Le slot (ou « emplacement ») : il désigne la fonction ou méthode qui sera appelée automatiquement lorsque le signal correspondant sera émis.
Ces deux concepts, intimement liés, sont au cœur de l’architecture événementielle...
Signal et slot
1. Introduction
Pour introduire l’utilisation des signaux et des slots en PyQt6, examinons un exemple simple. Nous allons créer une fenêtre héritée de QWidget, qui inclut un bouton affichant l’intitulé Fermer. Ce bouton, une fois cliqué, émet un signal qui déclenche un traitement simple dans le slot associé.
Voici le code minimal pour créer cette interface :
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout,
QPushButton
class FenetreSimple(QWidget):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
# Configuration de la fenêtre
self.setWindowTitle("Signaux et slots")
self.resize(250, 300)
self.move(50, 500)
# Création d'un layout vertical
self.disposition = QVBoxLayout()
# Création du bouton "Fermer"
self.fermer = QPushButton("Fermer")
...
Plus loin dans la gestion d’événements
1. La transmission de données
L’exemple précédent a introduit la connexion entre un signal et un slot, démontrant la manière d’exécuter une action en réponse à un événement. Cependant, les signaux ne se limitent pas à déclencher des actions : ils peuvent également transmettre des données. Cela est particulièrement utile lorsqu’un widget, comme un champ de saisie, contient une valeur que vous souhaitez transmettre à une autre partie de l’application.
Prenons un exemple pratique : nous allons créer une interface avec deux champs de saisie (QLineEdit). Chaque fois que l’utilisateur modifie le contenu du premier champ, ce texte est automatiquement copié dans le second champ.
Voici comment cela peut être réalisé :
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout,
LineEdit
class FenetreSimple(QWidget):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
self.setWindowTitle("Transmission de données")
self.resize(300, 200)
self.disposition = QVBoxLayout()
# Premier champ de saisie
self.edition = QLineEdit()
self.disposition.addWidget(self.edition)
# Deuxième champ de saisie
self.editionCopie = QLineEdit()
self.disposition.addWidget(self.editionCopie)
# Connexion du signal au slot
self.edition.textChanged.connect(self.exemple_slot)
self.setLayout(self.disposition)
def exemple_slot(self, texte_courant):
self.editionCopie.setText(texte_courant)
if __name__...
Développer sa propre gestion d’événements
1. Introduction
Nous avons vu comment utiliser les signaux natifs des widgets. Passons maintenant à la création de signaux personnalisés, qui permettent de concevoir des interactions spécifiques à vos besoins applicatifs.
2. Utilisation de pyqtSignal
Le module PyQt6.QtCore fournit la classe pyqtSignal pour créer vos propres signaux. Ces signaux peuvent transporter un ou plusieurs paramètres de types définis.
Prenons un premier exemple (rhétorique) :
from PyQt6.QtCore import pyqtSignal
# Signal transportant un entier
signal_entier = pyqtSignal(int)
# Signal transportant une chaîne de caractères
signal_chaine = pyqtSignal(str)
# Signal transportant plusieurs paramètres
signal_multiple = pyqtSignal(int, list, str)
Une fois défini, un signal peut être émis avec la méthode emit.
signal_entier.emit(42)
signal_multiple.emit(7, [1, 2, 3], "Bonjour")
3. Exemple de gestion personnalisée (pyqtSignal)
Imaginons une fenêtre avec un bouton :
-
Lors du clic, un premier signal est émis sans paramètre.
-
Un second signal est émis avec plusieurs paramètres.
Le code de cette fenêtre mobilisant l’usage de pyqtSignal est le suivant :
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout,
QPushButton
from PyQt6.QtCore import pyqtSignal
class FenetrePersonnalisee(QWidget):
# Définition des signaux
signal_simple = pyqtSignal()
signal_complexe = pyqtSignal(int, list, str)
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
self.setWindowTitle("Signaux personnalisés")
self.resize(300, 200)
self.layout = QVBoxLayout()
self.bouton = QPushButton("Cliquez-moi")
...
Conclusion
La gestion des événements en PyQt repose sur un système robuste de signaux et slots, qui permet de connecter des interactions utilisateur à des réponses programmatiques. Qu’il s’agisse d’utiliser des signaux intégrés, de créer des signaux personnalisés avec pyqtSignal, ou d’enrichir les connexions avec des fonctions comme lambda ou partial, PyQt offre une flexibilité remarquable pour gérer des comportements interactifs dans vos applications. Cette approche permet de structurer le code de manière modulaire tout en facilitant la maintenance et l’évolution des projets.
Dans le chapitre Disposition en PyQt/Le modèle MVC, nous explorerons les techniques de disposition des widgets en PyQt pour concevoir des interfaces graphiques ergonomiques et dynamiques. Nous découvrirons également l’architecture MVC (Modèle-Vue-Contrôleur), qui permet de séparer clairement les données, la logique métier et l’affichage pour une meilleure organisation des applications.