Interfaces graphiques
avec Python & tkinter
Wahb ZOUHRI
1
Introduction à tkinter
• tkinter est la bibliothèque graphique officielle de Python. Elle est incluse nativement - inutile de
faire pip install quoi que ce soit.
• Elle permet de créer des fenêtres, des boutons, des champs de saisie, des listes, des menus…
c'est-à-dire tout ce qui compose une interface graphique classique.
• tkinter fonctionne sur Windows, macOS et Linux sans aucune modification de votre code.
• Elle est basée sur Tcl/Tk, un outil graphique stable et mature. Elle est idéale pour apprendre la
programmation événementielle - programmer des réactions aux actions de l'utilisateur.
• Attention : sous Python 2, la bibliothèque s'appelait Tkinter avec un T majuscule. Avec Python 3
(version recommandée), c'est tkinter en minuscules.
Pour importer tkinter dans votre programme :
import tkinter as tk
# On utilise généralement l'alias ‘tk'.
2
La fenêtre principale
• Toute application tkinter commence par la création d'une fenêtre racine grâce à la classe Tk(). C'est le
conteneur principal dans lequel tous vos widgets seront placés.
• La dernière ligne est toujours mainloop(). C'est une boucle infinie qui maintient la fenêtre ouverte et attend les
actions de l'utilisateur. Sans elle, la fenêtre s'ouvre et se referme instantanément.
• Tout le code qui crée les widgets doit être placé AVANT l'appel à mainloop().
Structure minimale d'une application tkinter :
import tkinter as tk
# 1. Créer la fenêtre principale
fenetre = [Link]()
# 2. Configurer la fenêtre
[Link]('Ma première interface') # titre affiché dans la barre
# --- Ici on placera les widgets ---
# 3. Lancer la boucle (TOUJOURS en dernier)
[Link]()
3
Widgets - Label et Button
• Un widget est un composant graphique. Chaque widget est créé en passant la fenêtre parente comme premier
argument, puis des options de style (texte, couleur, police…).
• Le Label affiche du texte de façon statique - c'est juste un affichage, il ne réagit pas aux clics. On peut modifier
son texte plus tard avec configure(text='...').
• Le Button exécute une fonction quand l'utilisateur clique. On passe la fonction via command=. Attention : on
écrit command=ma_fonction SANS parenthèses - sinon la fonction est appelée immédiatement.
Commandes - Label et Button dans une fenêtre :
import tkinter as tk
fenetre = [Link]()
[Link]('Label et Button')
# Label : affiche un texte fixe
label = [Link](fenetre, text='Bonjour !', font=('Arial', 16, 'bold’))
# Button : exécute une fonction au clic
def changer_texte():
[Link](text='Vous avez cliqué !')
btn = [Link](fenetre, text='Cliquez ici', command=changer_texte) 4
Widget - Entry (saisie utilisateur)
• Le widget Entry est un champ de saisie sur une seule ligne. C'est lui qu'on utilise pour les formulaires : nom,
email, note, mot de passe…
• Pour lire ce que l'utilisateur a tapé, on appelle get() sur l'objet Entry. Elle renvoie une chaîne de caractères. On
utilise souvent .strip() pour supprimer les espaces en début et fin.
Exemple — formulaire de bienvenue :
champ = [Link](fenetre, width=30) # champ de saisie
def saluer():
prenom = [Link]().strip() # lire et supprimer les espaces
[Link]('Bonjour', f'Bienvenue, {prenom} !')
[Link](fenetre, text='Valider', command=saluer).
5
Mise en page - grid()
• grid() divise le conteneur en une grille de lignes (row) et de colonnes (column). On place chaque widget dans
une cellule. Les cellules s'adaptent automatiquement au contenu.
• sticky= contrôle l'alignement dans la cellule : 'W' colle à gauche, 'E' à droite, 'WE' s'étire sur toute la largeur.
padx= et pady= ajoutent des marges.
• columnspan= permet à un widget de s'étendre sur plusieurs colonnes — utile pour un bouton centré sous un
formulaire à deux colonnes..
import—tkinter
Exemple as avec
formulaire tk grid() :
fenetre = [Link]()
[Link]("Exemple d'interface")
[Link](fenetre, text = "Nom de l'etudiant").grid(row = 0, column = 0, sticky = "W", padx=5, pady =5)
[Link](fenetre, text = "ID de l'étudiant").grid(row = 1, column = 0, sticky = "W", padx=5, pady =5)
[Link](fenetre).grid(row = 0, column = 1, sticky = "W")
[Link](fenetre).grid(row = 1, column = 1, sticky = "W")
[Link](fenetre, text = "Ajouter élève").grid(row=0, column=2, rowspan=3, sticky = "w e n s", padx =
5, pady = 5)
[Link](fenetre, text = "Enregistrer").grid(row = 2, column = 0, columnspan= 2, sticky = "w e n s",
padx = 5, pady=5)
[Link]() 6
Exercice
Implémenter l’interface suivante (pour le moment sans comportement)
6
Variables tkinter
• tkinter propose des variables spéciales qui se synchronisent automatiquement avec les widgets. Quand la
variable change par code, le widget se met à jour tout seul - et inversement.
• On les lie à un widget via textvariable par exemple (pour Entry et Label). Il existe 4 types : StringVar() pour le
texte, IntVar() pour un entier, DoubleVar() pour un décimal, BooleanVar() pour vrai/faux.
• Pour lire : ma_var.get(). Pour modifier : ma_var.set('nouvelle valeur'). Dès l'appel à set(), tous les widgets liés se
mettent à jour instantanément sans aucune action supplémentaire.
Exemple - Entry et Label partagent la même StringVar :
import tkinter as tk
fenetre = [Link]()
[Link]('Variables tkinter')
ma_var = [Link]() # création de la variable
ma_var.set('Tapez quelque chose…') # valeur initiale
# Entry et Label partagent la même variable
[Link](fenetre, textvariable=ma_var, width=35).grid(row =0, column = 0, padx = 20, pady = 20)
[Link](fenetre, textvariable=ma_var).grid(row =1, column = 0, padx = 20, pady = 20)
[Link]()
7
Exercice
Compléter l’interface précédente de telle manière que, lors de l’appui sur le bouton « ajouter l’évaluation »,
le contenu des deux zones de texte soient affiché dans la console.
6
Événements et bind()
• L'option command= sur un bouton ne suffit pas toujours. Avec bind(), on peut lier n'importe quel événement
(clic, touche, survol) à n'importe quel widget.
• Syntaxe : [Link]('<NomEvenement>', ma_fonction). La fonction reçoit toujours un objet event avec des
informations : event.x et event.y (position souris), [Link] (touche pressée).
• Événements fréquents : <Button-1> clic gauche, <Button-3> clic droit, <Double-Button-1> double-clic, <Return>
touche Entrée, <KeyPress> n'importe quelle touche, <Enter>/<Leave> survol d'un widget.
• Si on bind sur la fenêtre elle-même ([Link](...)), l'événement se déclenche peu importe où se trouve le
focus.
Exemple — double-clic et touche Entrée :
label = [Link](fenetre, text='Double-cliquez sur moi !', font=('Arial',13))
[Link](row=0, column = 0)
def sur_double_clic(event): # event contient les infos du clic
[Link](text=f'Cliqué en ({event.x}, {event.y}) !')
def sur_entree(event): # [Link] = nom de la touche
[Link](text='Touche Entrée pressée !')
[Link]('<Double-Button-1>', sur_double_clic)
[Link]('<Return>', sur_entree) # lié à toute la fenêtre 9
Widget - Listbox
• La Listbox affiche une liste d'éléments que l'utilisateur peut sélectionner. On ajoute des éléments avec
insert([Link], 'texte') — [Link] signifie « ajouter à la fin ».
• Pour connaître la sélection, on appelle curselection() qui renvoie un tuple d'indices (ex : (1,) si le 2ème élément
est sélectionné). On récupère la valeur avec get(indice).
• On peut vider toute la liste avec delete(0, [Link]). Pour supprimer un seul élément (par ex. l'élément
sélectionné) : delete([Link]()[0]).
Exemple — Listbox avec Scrollbar et sélection :
frame = [Link](fenetre) # Frame = conteneur pour grouper des widgets
[Link](row = 0, column = 0, padx=10, pady=10)
scrollbar = [Link](frame)
[Link](side='right', fill='y')
liste = [Link](frame, yscrollcommand=[Link], height=6, width=30)
[Link](side='left')
[Link](command=[Link])
for e in ['Yassine ALAOUI','Nadia BENALI','Omar CHRAIBI','Sara DOUIRI']:
[Link]([Link], e)
def voir_selection():
idx = [Link]() # ex : (1,) si 2ème élément
if idx: print('Sélectionné :', [Link](idx[0]))
[Link](fenetre, text='Voir sélection', command=voir_selection).pack(pady=6) 10
Boîtes de dialogue
• tkinter fournit des boîtes de dialogue prêtes à l'emploi via ses sous-modules messagebox et filedialog — inutile
de les coder soi-même.
• [Link]() affiche une information neutre, showwarning() un avertissement (icône triangle),
showerror() une erreur. Chacune ouvre une fenêtre pop-up et attend que l'utilisateur clique OK.
Exemples :
from tkinter import messagebox, filedialog
[Link]( 'Information', 'Enregistrement réussi !')
[Link]('Attention', 'La note doit être entre 0 et 20.')
[Link]( 'Erreur', 'Fichier introuvable.')
11
Projet - Carnet de notes (1/2)
Ce projet combine tout ce que vous avez appris. L'utilisateur saisit un nom et une note, les ajoute à une liste, et peut
calculer la moyenne. Cette première partie crée la fenêtre, les variables et tous les widgets.
import tkinter as tk
from tkinter import messagebox
fenetre = [Link]()
[Link]('Carnet de notes')
# --- Variables tkinter ---
var_nom = [Link]() # liée au champ 'Nom'
var_note = [Link]() # liée au champ 'Note'
notes = {} # dictionnaire Python {nom: note}
# --- Labels et champs de saisie ---
[Link](fenetre, text='Nom :').grid( row=0, column=0, sticky='W', padx=10, pady=6)
[Link](fenetre, text='Note :').grid(row=1, column=0, sticky='W', padx=10, pady=6)
[Link](fenetre, textvariable=var_nom, width=25).grid(row=0, column=1, padx=10)
[Link](fenetre, textvariable=var_note, width=8 ).grid(row=1, column=1, sticky='W', padx=10)
# --- Listbox pour afficher les élèves ajoutés ---
liste = [Link](fenetre, height=8, width=40)
[Link](row=2, column=0, columnspan=2, padx=10, pady=8) 12
Projet — Carnet de notes (2/2)
# --- Fonctions ---
def ajouter():
nom = var_nom.get().strip() # lire et nettoyer la saisie
note = var_note.get().strip()
if not nom or not note: # vérifier que les champs ne sont pas vides
[Link]('Attention', 'Remplissez les deux champs !'); return
try:
notes[nom] = float(note) # convertir la note en nombre
[Link]([Link], f'{nom} - {note}/20')
var_nom.set(''); var_note.set('') # vider les champs
except ValueError:
[Link]('Erreur', 'La note doit être un nombre (ex: 14.5)')
def afficher_moyenne():
if not notes:
[Link]('Info', 'Aucune note enregistrée.'); return
moy = sum([Link]()) / len(notes)
[Link]('Résultats', f'{len(notes)} élève(s) - Moyenne : {moy:.2f}/20')
# --- Boutons ---
[Link](fenetre, text='Ajouter', command=ajouter, width=18).grid(row=3, column=0,
pady=6)
[Link](fenetre, text='Calculer moyenne', command=afficher_moyenne, width=18).grid(row=3, column=1,
pady=6)
[Link](fenetre, text='Quitter', command=[Link], width=38).grid(row=4, column=0,
columnspan=2)
13
[Link]()