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.
Ici, 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 - Fenêtre d'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 | 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")
|
- L1 : Importation du module
- L4 : Création d'un objet-fenêtre à partir de la classe Tk.
- L6 : Choix des dimensions de la fenêtre. On remarquera qu'on donne les dimensions de la fenêtre en pixels sous forme d'un string. On donne d'abord la largeur (600 pixels) puis la hauteur (300 pixels).
- L7 : Choix du titre de la fenêtre visible dans la barre supérieure
- L8 : Choix du fond coloré (bg stands for 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.
Exemple : rouge intense
fenetre.configure(bg="#FF0000")
Exemple : rouge foncé
fenetre.configure(bg="#880000")
Exemple : jaune
fenetre.configure(bg="#FFFF00")
On constate bien qu'on obtient du jaune par synthèse additive du rouge et du vert.
Comme il s'agit 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 ...)
La dernière ligne de votre application graphique sera toujours fenetre.mainloop()
ou équivalent.
1
2
3
4
5
6
7
8
9
10
11 | 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()
|
La méthode mainloop permet de lancer la surveillance des événements. Loop signifie bouclage, et main signifie principal.
2 - Widget Label
Le mot widget est la contraction de window et de gadget.
Création
Les widgets sont des objets et sont donc créés en utilisant un constructeur nommé Label.
monLabel = tk.Label(fenetre, ...)
Le premier paramètre à fournir est la référence d'un objet de type Tk. Ici, je donne donc fenetre puisqu'il s'agit du nom de la variable contenant la référence de ma fenêtre.
Les autres paramètres nommés possibles sont :
- text : le texte qu'on veut voir s'afficher dans le widget. Exemple
text="bonjour"
- fg : le foreground, la couleur de premier plan : la couleur du texte. Exemple
fg="white"
. - bg : le background, la couleur d'arrière plan, le fond du widget. Exemple :
bg="#333300"
- width : la largeur du widget en nombre de caractères si le widget contient du texte, comme ici
- height : la hauteur du widget. Correspond au nombre de lignes si le widget contient du texte, comme ici

Voilà le code, dont
- la création en ligne 11
- l'affichage dans la fenetre à l'aide de la méthode pack en ligne 12
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | 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()
|
Modification après création
Pour modifier un widget déjà créé, on peut utiliser la méthode configure qui permet de configurer ou reconfigurer les attributs du widget.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | 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 15 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 15 à 17 :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | 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 le Shell, on aura ceci :
>>> texte
'Bonjour'
>>> ecriture
'white'
>>> fond
'#884400'
>>> largeur
10
3 - Création d'événements à surveiller
Tout d'abord : qu'est-ce qu'un événement pour l'interface ? Il s'agit d'une modification de l'environnement extérieur : une touche de clavier sur laquelle on appuie, le déplacement de la souris, l'appui sur une touche de la souris ...
La traduction d'événement est event.
Lorsqu'on constate un événement / event, encore faut-il le gérer.
C'est le rôle du gestionnaire d'événement, qu'on traduit par event handler. C'est ce gestionnaire qui va donner l'ordre à la fonction désignée de s'activer si tel ou tel événement survient.
Pour créer une liaison événement - action à réaliser, il faut utiliser la méthode bind, appliquée au widget qu'on veut associer à l'événement.
Exemple Clic-gauche sur le label
Le clic-gauche est identifié par '<Button-1>'
. Si veut l'associer au widget monLabel de façon à ce qu'il lance la fonction ca_fonctionne lorsqu'on clique (gauche) sur le widget, il faut mettre ceci dans le code :
monLabel.bind('<Button-1>', ca_fonctionne)
Voici un code-exemple qui modifie l'affichage dans le Label à chaque fois qu'on clique dessus avec le bouton gauche.
Attention, la fonction ca_fonctionne ne peut pas être une fonction comme les autres : elle doit pouvoir recevoir un premier paramètre qui contiendra les données de l'événement. Nous en reparlerons juste après.
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()
|
Variante : les 3 boutons :
- Le clic-gauche est identifié par
'<Button-1>'
. - Le clic-molette est identifié par
'<Button-2>'
. - Le clic-droit est identifié par
'<Button-3>'
.
Variante : activation au relachement :
Les événements précédents 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 :
monLabel.bind('<ButtonRelease-1>', ca_fonctionne)
monLabel.bind('<ButtonRelease-2>', ca_fonctionne)
monLabel.bind('<ButtonRelease-3>', ca_fonctionne)
Objet Event
Le problème de la méthode précédente ? Si on a deux Labels sur lequels on veut faire pareil, on doit créer deux fonctions. On peut faire mieux.
L'objet event contient beaucoup d'informations sur l'événement, dont :
- L'identifiant-mémoire du widget ayant déclenché l'événement :
event.widget
- La coordonnée locale x de la souris dans le widget au moment de l'événement :
event.x
- La coordonnée locale y de la souris dans le widget au moment de l'événement :
event.y
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 | import tkinter as tk
# Déclaration des fonctions
def ca_fonctionne(event):
leLabel = event.widget
nouveau_texte = f"x={event.x} y={event.y}"
leLabel.configure(text=nouveau_texte)
# 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()
|
Coordonnées 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
.
Conclusion
Voici une liste des événements les plus utiles en lien avec la souris. La dernière colonne correspond au numéro permettant de savoir quel type d'événement a eu lieu avec event.type
.
Nom à utiliser dans bind | Description | Type (event.type) |
---|---|---|
'<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. |
4 |
'<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). | 5 |
'<Motion>' | L'utilisateur a bougé la souris au dessus du widget. Exemple : <fenetre.bind('<Motion>', action) | 6 |
'<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. | 7 |
'<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. | 8 |
Il en existe beaucoup d'autres. Allez voir la documentation externe si vous désirez faire quelque chose qui n'est pas réalisable avec ceux-ci.
La fenêtre principale de l'application 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.
Dans un premier temps, je parlerai donc simplement de la méthode place qui permet d'afficher les widgets en donnant les coordonnées x et 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.
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
# 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)
# Constantes
XMAX = 600
YMAX = 300
# 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 - After
Une dernière chose : 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.
On reprend l'exemple précédent mais cette fois, les Labels changent de place automatiquement toutes les 0.5 s
Comment ?
- On crée ligne 35 un tableau qui contient les références des Labels
- On active ligne 38 une fonction bouge
- Dans cette fonction (voir lignes 5 à 10) :
- On récupère avec une boucle for ... in (ligne 6) les références des widgets Labels.
- On tire aléatoirement deux coordonnées dans la fenêtre (lignes 7-8)
- On place le widget au nouvel emplacement (ligne 9)
- On lance l'appel récursif à la même fonction dans 500 ms, soit 0,5 (ligne 10).
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
# Déclaration des fonctions
def bouge():
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, bouge)
# Constantes
XMAX = 600
YMAX = 300
# 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
bouge()
# Surveillance des événements
fenetre.mainloop()
|
Article publié le 20 11 2019
Dernière modification : 24 11 2019
Auteur : ows. h.