Ajouter de l'interactivité !
Gérer les événements
Dans une fenêtre programmée à l'aide du module tkinter , les actions de l'utilisateur vont pouvoir modifier ou agir sur les widgets. Ces actions, appelées des événements, seront nécessaires au déclenchement de certaines fonctions.
L'instruction :
nom_widget.bind(nom_evenement, fonction)
associe l'événement nom_evenement au widget nom_widget (nom_evenement sera à piocher dans les tableaux ci-dessous).
Au déclenchement de l'événement, la fonction fonction est exécutée. Pour cela, la fonction doit avoir pour seul paramètre event :
def fonction(event):
"""La fonction « fonction » est associée à un événement."""
Quelques événements de la souris
nom_evenement | Description |
---|---|
'<Motion>' | Mouvement de la souris à l'intérieur du widget. |
'<Button-1>' | Clic (enfoncement) du bouton gauche ( 1 ) ou droit ( 3 ). |
'<ButtonRelease-3>' | Relâchement du bouton gauche ( 1 ) ou droit ( 3 ). |
'<Enter>' | La souris passe au-dessus du widget. |
'<Leave>' | La souris « sort » du widget. |
Quelques événements du clavier
nom_evenement | Description |
---|---|
'<h>' | Appui sur la touche h (par exemple) |
'<KeyRelease-h>' | Relâchement de la touche h (par exemple) |
Premier exemple
Exemple : Coordonnées de la souris...
Le but de cet exemple est de voir comment « lier » les mouvements de la souris au Canvas afin de récupérer les coordonnées de la souris et de les afficher à chaque mouvement (en temps réel) dans la zone de texte. Pour cela :
1 - Récupérer le programme suivant qui vous fournit une interface minimaliste :
##----- Importation des Modules -----##
from tkinter import *
##----- Création de la fenêtre -----##
fenetre = Tk()
fenetre.title('Mouvements de la souris')
##----- Création des boutons -----##
bouton_quitter = Button(fenetre, text='Quitter', command=fenetre.destroy)
bouton_quitter.grid(row=2, column=1, padx=3, pady=3, sticky=S+W+E)
##---- Création des zones de texte -----##
message = Label(fenetre, text='Ici du texte.')
message.grid(row=0, column=0, columnspan=2, padx=3, pady=3, sticky=W+E)
##----- Création du canevas -----##
dessin=Canvas(fenetre, bg="white", width=300, height=400)
dessin.grid(row = 1, column = 0, columnspan = 2, padx=5, pady=5)
##----- Programme principal -----##
fenetre.mainloop() # Boucle d'attente des événements
2 - Dans le programme principal, appliquer la méthode .bind() au canevas dessin. Associer l'événement de mouvement de la souris à une fonction nommée afficher() .
3 - Définir la fonction afficher()
. Les coordonnées de la souris sont obtenues avec event.x
et event.y
.
Attention, la fonction afficher()
doit aussi paramétrer la zone de texte pour afficher en temps réel les coordonnées de la souris dans le canevas.
4 - Et pour l’événement "clic de souris" ?
Animer automatiquement
Animer un objet graphique revient à faire du dessin animé : on redéfinit sa position (donc on redéfinit les paramètres de l'objet) après une action de l'utilisateur (un événement) ou après un laps de temps prédéfini (on parle dans ce cas d'animation automatique). Dans ce dernier cas, la fonction qui «pilote» la redéfinition des objets graphiques fait appel à elle-même après ce cours laps de temps. La méthode .after()
permet ce type d'appel récursif.
L'instruction :
fenetre.after(temps, fonction)
relance l'exécution de fonction dans fenetre toutes les temps millisecondes.
Deuxième exemple
Exemple :
On souhaite lancer une animation qui permet d'afficher des cercles de couleur rouge de manière aléatoire sur notre zone canevas. On vous fournit l'interface graphique minimale (on remarquera l'usage de la méthode .pack() pour les placement des différents objets graphiques) :
##----- Importation des Modules -----##
from tkinter import *
##----- Création de la fenêtre principale -----##
fenetre = Tk()
fenetre.title('Animation cercles aléatoires')
##----- Création d'un widget Canvas -----##
Largeur = 400
Hauteur = 300
Canevas = Canvas(fenetre, width = Largeur, height =Hauteur, bg ='white')
Canevas.pack(padx =5, pady =5)
##----- Création du bouton Démarrer -----##
BoutonGo = Button(fenetre, text ='Démarrer', command = demarrer)
BoutonGo.pack(side = LEFT, padx = 10, pady = 10)
##----- Création du bouton Arrêter -----##
BoutonArreter = Button(fenetre, text ='Arrêter', command = arreter)
BoutonArreter.pack(side = LEFT, padx = 5, pady = 5)
##----- Création du bouton Quitter -----##
BoutonQuitter = Button(fenetre, text ='Quitter', command = fenetre.destroy)
BoutonQuitter.pack(side = LEFT, padx = 5, pady = 5)
##----- Programme principal -----##
fenetre.mainloop()
1 - Récupérer l'interface minimale ci-dessus. Le programme ne se lance pas car les fonctions demarrer() et arreter() ne sont pas encore définies.
2 - Si on clique sur le bouton Démarrer, on veut lancer la fonction demarrer() qui va lancer l'animation des cercles.
Définir cette fonction cercle(). Pour cela, on tracera un cercle de rayon 10 et de centre un tirage aléatoire compris entre la hauteur et la largeur de notre canevas. Puis simuler.
3 - En lançant l'animation, on lance qu'un seul cercle. En utilisant la méthode .after(), on peut faire afficher une multitude de cercles très simplement. On pourra choisir 500 ms comme intervalle de temps.
4 - Pour autoriser ou interdire une animation, on utilise généralement un drapeau , c'est-à-dire une variable globale booléenne (ie : qui ne peut prendre que 2 valeurs : TRUE ou FALSE).
Appelons cette variable animation
. A quelle valeur doit être initialisée cette variable ?
5 - A l'aide de notre drapeau animation
, nous allons pouvoir gérer les 2 boutons démarrer
et arrêter
.
L'algorithme de l'utilisation du drapeau sera le suivant :
Initialisation de la variable
animation
Appui sur le bouton demarrer :
On efface le canevas avec la méthode .delete(ALL)
On teste si la variable globale
animation
est à fauxsi oui, alors on met
animation
à vraie et on lance cercle()Appui sur le bouton arrêter :
on met la variable à faux
Dans la fonction cercle, on teste si
animation
est vraie ; si oui, alors, on utilise la méthode .after().
Pour les plus rapides, on pourra faire apparaître des cercles de couleurs et de tailles différentes, toujours tirés aléatoirement...