Fiche Tkinter pour Python
Fiche qui précise comment créer des fenêtre basiques avec la bibliothèque tkinter.
D'autres fiches tkinter permettront de détailler d'autres aspects.
Dans cette fiche, on part à l'essentiel pour réaliser une application comportant des zones qu'on peut colorer, sur lesquelles on peut écrire et cliquer pour provoquer des effets.
1 - Créer une fenêtre pour l'application
tkinter est le nom d'une des bibliothèques qui permet de réaliser des interfaces graphiques. Il ne s'agit pas de la plus performante, de la plus jolie mais elle a l'intêret d'être assez présente sur le Web. On peut ainsi trouver beaucoup d'exemples assez facilement. Et de ne pas être trop complexe à prendre en main pour réaliser de petites applications non profesionnelles.
Le module est installé de base avec les versions Python disponibles sous Windows.
Voici un code basique permettant de créer une fenêtre graphique :
1
2
3
4
5
6
7
8
9
10
11
12 | import tkinter as tk
# Création de la fenêtre du logiciel
fenetre = tk.Tk()
# Configuration de la fenêtre
fenetre.geometry("600x300")
fenetre.title("Ma super application")
fenetre.configure(bg="black")
# Surveillance des événements
fenetre.mainloop()
|
- Ligne 1 : Importation du module et création de l'alias tk.
- Ligne 4 : Création d'un objet-fenêtre nommé fenetre à partir de la classe Tk.
- Ligne 7 : Choix des dimensions de la fenêtre avec la méthode geometry à qui on fournit les dimensions sous forme d'un string : largeur (600 pixels) puis hauteur (300 pixels).
- Ligne 8 : Choix du titre de la fenêtre avec la méthode title, visible dans la barre supérieure
- Ligne 9 : Modification du fond coloré avec la méthode configure (bg pour background). On donne la couleur sous forme d'un string. On peut donner une couleur prédéfinie ou la choisir en utilisant les trois intensités RGB sous forme hexadécimale #RRGGBB. Les intensités hexadécimales varient entre
- 00 (la plus faible) et
- FF (la plus forte)
- Exemples
- Ligne 12 : la méthode mainloop permet de lancer la surveillance des événements. Loop signifie bouclage, et main signifie principal. S'agissant d'une interface graphique, le principe est de passer en programmation événementielle et donc de surveiller les événements : clicks sur l'écran, touches claviers activées ...
# rouge
fenetre.configure(bg="#FF0000")
# rouge foncé
fenetre.configure(bg="#880000")
# jaune
fenetre.configure(bg="#FFFF00")
La dernière ligne de votre application graphique sera donc toujours fenetre.mainloop() ou équivalent.
2 - Création du Widget Label (pour le texte)
Le mot widget est la contraction de window et de gadget.
Trois parties :
- Création et configuration
- Modification après création
- Lecture du contenu
Voici le code que nous allons analyser :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | import tkinter as tk
# Création de la fenêtre du logiciel
fenetre = tk.Tk()
# Configuration de la fenêtre
fenetre.geometry("600x300")
fenetre.title("Ma super application")
fenetre.configure(bg="black")
# Création-configuration d'un Label et affichage
monLabel = tk.Label(fenetre, text = "Bonjour", fg="white", bg="#884400", width=10, height=5)
monLabel.pack()
# Surveillance des événements
fenetre.mainloop()
|
2.1 - Création
Les widgets sont des objets et sont donc créés en utilisant un constructeur nommé Label.
12 | monLabel = tk.Label(fenetre, ... plein d'autres arguments envoyés)
|
Le premier paramètre à fournir est la référence d'un objet de type Tk. Ici, je donne donc fenetre, le nom de la variable contenant la référence de la fenêtre dans le code précédent. Exemple (cette ligne seule ne suffit pas attention ):
12 | monLabel = tk.Label(fenetre, text="Bonjour", fg="white", bg="#884400", width=10, height=5)
|
Les autres paramètres nommés possibles sont :
text="Bonjour"
permet de fournir le texte qu'on veut voir s'afficher dans le widget.fg="white"
permet de renseigner le foreground, la couleur du texte au premier plan..bg="#884400"
: le background, la couleur d'arrière plan du widget.width=10
: la largeur du widget (en nombre de caractères si le widget contient du texte).height=5
: la hauteur du widget. Correspond au nombre de lignes si le widget contient du texte, comme ici

L'utilisation se fait en deux temps :
- la création en mémoire en ligne 12
- l'affichage réel dans la fenetre à l'aide de la méthode pack en ligne 13
12
13 | monLabel = tk.Label(fenetre, text = "Bonjour", fg="white", bg="#884400", width=10, height=5)
monLabel.pack()
|
2-2 Modification après création
Pour modifier les attributs d'un widget, on utilise la méthode configure.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | import tkinter as tk
# Création de la fenêtre du logiciel
fenetre = tk.Tk()
# Configuration de la fenêtre
fenetre.geometry("600x300")
fenetre.title("Ma super application")
fenetre.configure(bg="black")
# Création et configuration d'un Label puis affichage
monLabel = tk.Label(fenetre, text = "Bonjour", fg="white", bg="#884400", width=10, height=5)
monLabel.pack()
# Modification du Label
monLabel.configure(text="NEW !", fg="black", bg="#BBBBFF")
# Surveillance des événements
fenetre.mainloop()
|
La ligne 16 permet de modifier les valeurs choisies au départ. Le carré n'affichage plus le même texte et n'a plus la même couleur.

Lecture des attributs
Si vous voulez lire et enregistrer la valeur d'un attribut d'un widget, il faut utiliser la méthode cget.
En voici quelques exemples sur les lignes 16 à 18 :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 | import tkinter as tk
# Création de la fenêtre du logiciel
fenetre = tk.Tk()
# Configuration de la fenêtre
fenetre.geometry("600x300")
fenetre.title("Ma super application")
fenetre.configure(bg="black")
# Création et configuration d'un Label puis affichage
monLabel = tk.Label(fenetre, text = "Bonjour", fg="white", bg="#884400", width=10, height=5)
monLabel.pack()
# Récupération des valeurs des attributs
texte = monLabel.cget("text")
ecriture = monLabel.cget("fg")
fond = monLabel.cget("bg")
largeur = monLabel.cget("width")
# Surveillance des événements
fenetre.mainloop()
|
Si on lance l'application, qu'on la ferme et qu'on tente de voir le contenu des variables dans la console, on aura ceci :
>>> texte
'Bonjour'
>>> ecriture
'white'
>>> fond
'#884400'
>>> largeur
10
3 - Création d'événements à surveiller
Voici le code permettant de modifier le texte du label lorsqu'on clique dessus :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 | import tkinter as tk
# Déclaration des fonctions
def ca_fonctionne(event) :
lecture = monLabel.cget('text')
if lecture == "Bonjour" :
monLabel.configure(text="Ca va ?")
else :
monLabel.configure(text="Bonjour")
# Création de la fenêtre du logiciel
fenetre = tk.Tk()
# Configuration de la fenêtre
fenetre.geometry("600x300")
fenetre.title("Ma super application")
fenetre.configure(bg="black")
# Création et configuration d'un Label puis affichage
monLabel = tk.Label(fenetre, text = "Bonjour", fg="white", bg="#884400", width=10, height=5)
monLabel.pack()
# Activation des événements à surveiller
monLabel.bind('<Button-1>', ca_fonctionne)
# Surveillance des événements
fenetre.mainloop()
|
3.1 Création d'un premier événement
Evénement
Qu'est-ce qu'un événement pour l'interface ?
Il s'agit d'une modification de l'environnement extérieur : une touche du clavier ou de la souris sur laquelle on appuie, le déplacement de la souris...
La traduction d'événement est event.
Lorsqu'on constate un événement, encore faut-il le gérer. C'est le rôle du gestionnaire d'événement, qu'on traduit par event handler.
Voici un exemple où le clic gauche sur le label modifie le contenu :
Gestionnaire d'événement et fonction-événement Tkinter
C'est ce gestionnaire qui va donner l'ordre d'activer une fonction particulière si cet événement survient.
Pour faire la liaison événement à surveiller ↦ fonction à réaliser, on utilise la méthode bind, appliquée au widget qu'on surveille.
Codification de la liaison avec bind
- On active sur le label monLabel
- la surveillance d'un clic-gauche, identifié par
'<Button-1>'
- qui provoque l'appel à la fonction nommée ca_fonctionne
24
monLabel.bind('<Button-1>', ca_fonctionne)
Fonction-événement Tkinter :
La fonction ca_fonctionne de Tkinter n'est pas une fonction comme les autres : elle DOIT possèder un premier paramètre qui va se remplir automatiquement avec les données de l'événement. Nous en reparlerons juste après.
4 | def ca_fonctionne(event):
|
On note souvent ce paramètre event, e, evt... mais vous pouvez le nommer comme vous voulez : sachez juste que Tkinter va remplir le premier paramètre avec les informations sur l'événement, quelque soit son nom !
Si on analyse le code de notre exemple, notre fonction n'utilise absolument pas le paramètre event dans son code interne, mais il doit être présent dans les paramètres :
4
5
6
7
8
9 | def ca_fonctionne(event) :
lecture = monLabel.cget('text')
if lecture == "Bonjour" :
monLabel.configure(text="Ca va ?")
else :
monLabel.configure(text="Bonjour")
|
Variable globale monLabel
Notez bien que pour l'instant, nous profitons du fait qu'on peut lire les variables globales depuis une fonction.
Nous verrons plus bas comment programmer l'interface plus proprement.
3.2 Les autres événements sur les touches de la souris
Détection des clics sur les 3 boutons de la souris
24 | monLabel.bind('<Button-3>', ca_fonctionne)
|
- Le clic-gauche est identifié par
'<Button-1>'
. - Le clic-molette est identifié par
'<Button-2>'
. - Le clic-droit est identifié par
'<Button-3>'
.
Détection du relachement d'un bouton
Les événements "clics" sont activés dès qu'on appuie. Parfois, il est plus prudent de ne l'activer qu'au relachement. Comment ? En utilisant plutôt ceci :
24 | monLabel.bind('<ButtonRelease-1>', ca_fonctionne)
|
'<ButtonRelease-1>'
pour le bouton de gauche'<ButtonRelease-2>'
pour le bouton central'<ButtonRelease-3>'
pour le bouton de droite
3.3 Utilisation du paramètre event
Jusqu'à présent, nous avons agi sur monLabel en lisant directement son adresse, déclarée dans le programme principal. Ce n'est pas une très belle façon de programmer.
Objet Event : widget activé et position LOCALE de la souris lors de l'événement
L'objet event contient beaucoup d'informations sur l'événement. Voici comment en récupérer quelques unes :
- event.widget : l'identifiant-mémoire du widget ayant déclenché l'événement.
- event.x : la coordonnée locale x de la souris dans le widget au moment de l'événement
- event.y : la coordonnée locale y de la souris dans le widget au moment de l'événement
Exemple d'utilisation
Voici une interface munie de deux labels : lorsqu'on clique sur l'un des labels, la fonction détecte sur quel label on vient de cliquer et on y affiche les coordonnées LOCALES de la souris sur ce label :
- (0,0) en haut à gauche et
- (xMAX, yMAX) en bas à droite.
Les coordonnées sont locales car quel que soit le label sur lequel on clique, on obtient les coordonnées de la souris sur ce widget, pas sur l'écran.
Voici le code correspondant :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 | import tkinter as tk
# Déclaration des fonctions
def ca_fonctionne(event):
leLabel = event.widget
leLabel.configure(text=f"x={event.x} y={event.y}")
# Création de la fenêtre du logiciel
fenetre = tk.Tk()
# Configuration de la fenêtre
fenetre.geometry("600x300")
fenetre.title("Ma super application")
fenetre.configure(bg="black")
# Création et configuration des Labels puis affichage
monLabel1 = tk.Label(fenetre, text="Label 1 !", fg="white", bg="#884400", width=10, height=5)
monLabel2 = tk.Label(fenetre, text="Label 2 !", fg="white", bg="#448800", width=10, height=5)
monLabel1.pack()
monLabel2.pack()
# Activation des événements à surveiller
monLabel1.bind('<Button-1>', ca_fonctionne)
monLabel2.bind('<Button-1>', ca_fonctionne)
# Surveillance des événements
fenetre.mainloop()
|
Objet Event : récupérer le type de l'événement
On peut récupérer avec event.type le type de l'événement qui a déclenché l'appel à votre fonction. On peut ainsi créer éventuellement une fonction générique qui agit différemment en fonction des cas.
Les valeurs sont données dans la première colonne. Ainsi, si un événement possède un type 7, c'est qu'il correspond à la surveillance des entrées dans un widget.
Type (event.type) | Evénement | Description |
---|---|---|
4 | '<Button-X>' | L'utilisateur vient d'appuyer sur l'un des boutons de la souris. Exemple : <fenetre.bind('<Button-1>', action) pour lier l'action à toute l'application. |
5 | '<ButtonRelease-1>' | L'utilisateur vient de relacher l'un des boutons de la souris. Exemple : '<ButtonRelease-1>' . A priviligier par rapport au type 4 : l'utilisateur peut sortir du widget pour désactiver son action en cas d'erreur, alors que l'exécution est automatique en cas de type 4 (Button). |
6 | '<Motion>' | L'utilisateur a bougé la souris au dessus du widget. Exemple : <fenetre.bind('<Motion>', action) |
7 | '<Enter>' | L'utilisateur vient de faire rentrer la souris dans le Widget. Exemple : <monLabel.bind('<Enter>', action) L'activation ne se fait que lors de la rentrée. |
8 | '<Leave>' | L'utilisateur vient de faire sortir la souris d'un Widget Exemple : <monLabel.bind('<Enter>', action) L'activation ne se fait que lors de la sortie. |
Il en existe beaucoup d'autres. Allez voir la documentation si vous désirez faire quelque chose qui n'est pas réalisable avec ceux-ci.
Objet Event : coordonnées ABSOLUES sur l'écran
On peut aussi obtenir les coordonnées du clic sur l'écran en lui-même.
Le point (0,0) est alors le coin supérieur gauche de votre écran, plus du widget lui-même.
Il suffit d'évaluer event.x_root et event.y_root.
Remarque : la fenêtre principale de l'application (fenetre dans le code-exemple) contient également la méthode bind. Vous pouvez donc l'utiliser pour obtenir la position de la souris sur l'application.
4 - Placement des widgets avec place
Pour l'instant, les widgets se placent les uns sous les autres car on utilise simplement la méthode de placement pack sans lui fournir de paramètres.
On peut faire mieux avec cette méthode mais le but n'est pas de faire de vous des spécialistes de Tkinter.
Je parlerai donc simplement de la méthode place.
Méthode d'affichage place
La méthode place permet d'afficher les widgets dans une fenêtre en imposant les coordonnées (x, y) où on veut voir apparaitre le coin supérieur gauche du widget concerné.
Exemple : monLabel.place(x=50, y=100)

A titre d'exemple, une application où le Label texte bouge aléatoirement de place à chaque fois qu'on clique dessus.
- Lors de la création initiale, on place précisement les widgets (lignes 26 et 27)
- Dans la fonction bouge, on utilise à nouveau la méthode place en fournissant des coordonnées aléatoires.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 | import tkinter as tk
import random as rd
# Constantes
XMAX = 600
YMAX = 300
# Déclaration des fonctions
def bouge(event):
leLabel = event.widget
x = rd.randint(0, XMAX)
y = rd.randint(0, YMAX)
leLabel.place(x=x, y=y)
# Création de la fenêtre du logiciel
fenetre = tk.Tk()
# Configuration de la fenêtre
fenetre.geometry(f"{XMAX}x{YMAX}")
fenetre.title("Ma super application")
fenetre.configure(bg="black")
# Création et configuration des Labels puis affichage
monLabel1 = tk.Label(fenetre, text="Label 1 !", fg="white", bg="#884400", width=10, height=5)
monLabel2 = tk.Label(fenetre, text="Label 2 !", fg="white", bg="#448800", width=10, height=5)
monLabel1.place(x=50, y=50)
monLabel2.place(x=100, y=100)
# Activation des événements à surveiller
monLabel1.bind('<Button-1>', bouge)
monLabel2.bind('<Button-1>', bouge)
# Surveillance des événements
fenetre.mainloop()
|
5 - Créer des animations avec after
Méthode after
La méthode after appliquée à votre application permet de relancer automatiquement la fonction-argument au bout d'un certain temps exprimée en ms.
10 | fenetre.after(500, deplacement)
|
Ici, on demande donc de lancer un appel à la fonction deplacement au bout de 500 ms, soit 0.5 s.
- 1000 ms = 1 s
- 500 ms = 0.5 s
- 100 ms = 0.1 s
- 10 ms = 0.01 s
- 1 ms = 0.001 s
Reprenons l'exemple précédent mais cette fois, les Labels changent de place automatiquement toutes les 0.5 s. Il n'y aura ici aucun événement à surveiller, tous les déplacements sont automatiques.
Comment ?
- On crée ligne 35 un tableau lesLabels qui contient les références des Labels
- On active ligne 38 la fonction deplacement
- Dans cette fonction (voir lignes 10 à 14) :
- On récupère avec une boucle for ... in (ligne 10) les références successsives des widgets Labels dans la variable de boucle widget. Attention : on lit directement la variable globale lesLabels.
- On tire aléatoirement deux coordonnées x et y dans la fenêtre (lignes 11-12)
- On place avec place le widget aux nouvelles coordonnées (ligne 13)
- On lance avec after l'appel à la même fonction deplacement dans 500 ms, soit 0,5 (ligne 14).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 | import tkinter as tk
import random as rd
# Constantes
XMAX = 600
YMAX = 300
# Déclaration des fonctions
def deplacement():
for widget in lesLabels :
x = rd.randint(0, XMAX - 80)
y = rd.randint(0, YMAX - 80)
widget.place(x=x, y=y)
fenetre.after(500, deplacement)
# Création de la fenêtre du logiciel
fenetre = tk.Tk()
# Configuration de la fenêtre
fenetre.geometry(f"{XMAX}x{YMAX}")
fenetre.title("Ma super application")
fenetre.configure(bg="black")
# Création et configuration des Labels puis affichage
monLabel1 = tk.Label(fenetre, text="Label 1 !", fg="white", bg="#884400", width=10, height=5)
monLabel2 = tk.Label(fenetre, text="Label 2 !", fg="white", bg="#448800", width=10, height=5)
monLabel3 = tk.Label(fenetre, text="Label 3 !", fg="white", bg="#008844", width=10, height=5)
monLabel4 = tk.Label(fenetre, text="Label 4 !", fg="white", bg="#004488", width=10, height=5)
monLabel1.place(x=50, y=50)
monLabel2.place(x=100, y=100)
monLabel3.place(x=300, y=100)
monLabel4.place(x=200, y=200)
# Création de la liste des widgets à gérer
lesLabels = [monLabel1, monLabel2, monLabel3, monLabel4]
# Activation de la fonction d'animation automatique
deplacement()
# Surveillance des événements
fenetre.mainloop()
|
Article publié le 20 11 2019
Dernière modification : 24 11 2019
Auteur : ows. h.