Une application Tkinter consiste essentiellement en une boucle, déclenchée par la méthode mainloop(), scrutant les événements (events). Ces événements peuvent provenir du clavier (touche frappée, enfoncée, relâchée), de la souris (clic gauche ou droit, glisser/déplacer...) ou du programme lui-même.
La détection de ces événements est automatique, il suffit de spécifier comment lier un événement particulier à l'action qui doit lui correspondre.
C'est l'objet de la méthode bind()
(lier en anglais).
Sa syntaxe est de la forme cible.bind(événement e,
callback)
où la fonction associée callback admet au minimum un paramètre formel noté, pour des raisons de clarté, event
ou e
(mais tout autre nom de variable convient). Cette ligne de code se lit : "au cas où l'événement e se produit, appeler la fonction callback(e)
".
cible
désigne une fenêtre, un cadre, un widget ou un objet graphique.
L'attribut event.char
(e.char
) contient alors le caractère tapé.
Il est possible de surveiller plusieurs événements simultanément en utilisant plusieurs fois la méthode bind()
.
Nom des événements liés aux touches du clavier :
Exemple : jeu.bind("<Left>", callback)
appelle la fonction callback(event) lorsque la flèche gauche ← du clavier est frappée.
On souhaite à présent que la vérification du calcul soit déclenchée par la touche "Entrée" ("Enter" ou "Return") du clavier et pas seulement par un bouton.
On lie (méthode bind()) pour cela un événement clavier (ici "<Return>") à la fonction afficheResultat : ajouter la ligne nécessaire dans la boucle mainloop.
Tester le code,
un message d'erreur apparaît : TypeError: afficheResultat() takes 0 positional arguments but 1 was given
En effet, la méthode bind est associée à un événement (event)
qui est transmis par bind à la fonction qui n'attend aucun paramètre, d'où le message d'erreur. On corrige ce problème en ajoutant un paramètre e dans la fonction afficheResultat :
def afficheResultat(e):
Tester le code par validation (tout va bien) puis par entrée, un nouveau message d'erreur apparaît : TypeError: afficheResultat()
missing 1 required positional argument: 'e'
, ce qui est normal car l'appel par le bouton ne transmet aucun paramètre ici. Ce problème est résolu en indiquant que la valeur
par défaut du paramètre est None (aucune valeur). L'en-tête de la fonction devient donc def afficheResultat(e=None):
Ce qui lui permet d'être appelée avec ou sans argument (on peut aussi écrire def afficheResultat(*e):
ce qui autorise un nombre variable d'arguments lors de l'appel de la fonction).
Tester le code.
Ecrire une application permettant de déplacer un rectangle dans une fenêtre à l'aide des flèches de direction du clavier.
Syntaxe 1
Syntaxe 2
Observer le résultat dans la console.
Syntaxe 1
La méthode focus_force()
permet de rendre la fenêtre créée par Tkinter active. C'est alors cette fenêtre qui possède le "focus", c'est à dire la fenêtre qui est située au "premier plan".
Sans cette instruction, les caractères tapés au clavier concerneront la fenêtre active (qui ne sera pas la fenêtre Tkinter).
Rq : cette même méthode permet également de donner le focus à un widget en particulier.
La ligne essentielle est jeu.bind("<Key>", afficheCarac)
. La méthode bind()
lie la frappe d'une touche quelconque ("<Key>"
) à une fonction qui effectue une action, afficheCarac(event)
, dans cet exemple.
L'attribut char
de l'événement event
contient le caractère tapé (sauf touches spéciales).
Syntaxe 2
La seule différence réside dans l'utilisation d'une fonction lambda (qui convient très bien dans le cas d'une action très simple qui ne nécessite pas d'écrire une fonction) :jeu.bind("<Key>", lambda event: print(event.char))
.
Le nom de variable "event" est quelconque, on peut tout aussi bien écrire : jeu.bind("<Key>", lambda e: print(e.char))
.