Fiche de révision : Introduction à la programmation GUI avec Tkinter

📋 Plan du Cours

  1. Paradigme événementiel et mainloop
  2. Créer une fenêtre Tkinter avec racine
  3. Tkinter classique et widgets ttk
  4. Widgets fondamentaux et création parent options
  5. Treeview pour afficher des données
  6. Gestionnaires de géométrie pack et grid
  7. Règle d’or pack et grid sans mélange
  8. grid avancé span et sticky
  9. Structurer avec les Frame conteneurs
  10. Callbacks command et bind avec Event

📖 1. Paradigme événementiel et mainloop

🔑 Notions clés & Définitions

  • Programmation événementielle : Approche où l’interface réagit aux actions de l’utilisateur plutôt que d’exécuter un script linéaire jusqu’à la fin.
  • Mainloop : Boucle principale d’une GUI qui maintient l’application active et l’écoute des événements tant que la fenêtre existe.
  • Script procédural : Programme exécuté de façon séquentielle, ligne par ligne, où le code contrôle le déroulement et s’arrête après l’exécution.
  • Événement : Signal déclenché par une interaction (clic, frappe clavier, survol) auquel l’interface peut répondre via des gestionnaires.

📝 Points essentiels

  • Dans un script procédural, l’exécution suit l’ordre des lignes puis le programme s’arrête.
  • Dans une GUI, l’utilisateur devient maître du temps : le programme affiche la fenêtre puis attend des interactions.
  • La mainloop fait tourner une boucle infinie d’écoute tant que l’interface doit rester réactive.
  • L’interface ne réagit que lorsqu’un événement survient (clic, clavier, survol).
  • La programmation événementielle remplace la logique “input() puis attente” par une logique “attendre des événements”.
  • Les GUI sont conçues pour rester actives sans bloquer l’application pendant que l’utilisateur interagit.

💡 Astuce mémo

Procédural = “je déroule”, GUI = “j’écoute” : Mainloop = boucle d’écoute infinie.

📖 2. Créer une fenêtre Tkinter avec racine

🔑 Notions clés & Définitions

  • Racine Tkinter : La racine est la fenêtre principale créée par Tkinter, point de départ de l’interface et conteneur des widgets.
  • tk.Tk() : La fonction tk.Tk() instancie la fenêtre principale (la racine) et prépare la boucle d’événements pour l’interface.
  • mainloop() : La méthode mainloop() lance la boucle principale qui bloque le programme et traite les événements jusqu’à fermeture de la fenêtre.
  • Programmation événementielle : La programmation événementielle fait réagir l’interface uniquement quand un événement survient, au lieu d’exécuter une boucle procédurale bloquante.
  • ttk (Themed Tkinter) : ttk est la surcouche de Tkinter qui fournit des widgets au style natif du système d’exploitation, plus modernes que tk classique.

📝 Points essentiels

  • Le code minimal crée la racine avec root = tk.Tk(), puis configure titre et taille avant d’appeler root.mainloop().
  • root.mainloop() bloque l’exécution et attend la fermeture de la fenêtre, après quoi le programme peut continuer.
  • La fenêtre peut être dimensionnée via root.geometry("400x300"), où la valeur est largeur x hauteur en pixels.
  • En Tkinter classique, les widgets de base (ex. tk.Button) peuvent avoir un look ancien, tandis que ttk vise un rendu natif (ex. Windows 11, macOS, Linux).
  • Depuis Python 3.1, on privilégie ttk pour les widgets afin d’obtenir une apparence plus moderne.
  • La logique d’instanciation est présentée comme identique entre Java Swing et Tkinter : créer la fenêtre, régler titre/taille, puis rendre/relancer la boucle d’événements.

💡 Astuce mémo

Racine = fenêtre (tk.Tk) ; mainloop = écoute infinie : Tk = “Top-level”, mainloop = “Main écoute”.

📖 3. Tkinter classique et widgets ttk

🔑 Notions clés & Définitions

  • Tkinter : Tkinter est la bibliothèque Python qui permet de créer des interfaces graphiques avec une fenêtre principale et des widgets.
  • tk.Button : tk.Button est un widget classique de Tkinter qui crée un bouton cliquable avec un texte affiché.
  • ttk.Button : ttk.Button est un bouton fourni par le module ttk, conçu pour des widgets modernes et généralement à privilégier.
  • Widget (Window Gadget) : Un widget est un élément visuel de l’interface graphique, comme un bouton, un champ de saisie ou un tableau.
  • ttk.Treeview : ttk.Treeview est un widget qui affiche des listes d’objets sous forme de tableau interactif avec colonnes.

📝 Points essentiels

  • L’importation typique sépare Tk classique et ttk via import tkinter as tk et from tkinter import ttk.
  • La création d’une fenêtre passe par root = tk.Tk(), puis l’exécution de l’interface par root.mainloop().
  • Un widget doit être placé avec un gestionnaire de géométrie (layout) pour apparaître à l’écran.
  • Les widgets ttk sont à privilégier pour obtenir des composants plus modernes que les widgets tk classiques.
  • La syntaxe de création suit ttk.NomDuWidget(parent, option1=valeur, option2=valeur...).
  • Pour ttk.Treeview, show="headings" masque la colonne arborescente et affiche des en-têtes de colonnes.

💡 Astuce mémo

tk = ancien, ttk = moderne : si tu hésites, choisis ttk ; sans layout, rien ne s’affiche.

📖 4. Widgets fondamentaux et création parent options

🔑 Notions clés & Définitions

  • ttk.Treeview : Widget de table arborescente permettant d’afficher des lignes et colonnes avec des en-têtes configurables.
  • tableau.heading : Méthode de Treeview qui définit le texte affiché pour chaque en-tête de colonne.
  • tableau.insert : Méthode de Treeview qui ajoute une ligne (valeurs de colonnes) dans le parent et à une position donnée.
  • parent="" : Valeur indiquant que l’élément Treeview est inséré à la racine, donc au niveau supérieur.
  • pack() : Gestionnaire de géométrie Tkinter qui empile les widgets horizontalement ou verticalement selon des options.

📝 Points essentiels

  • Treeview se crée avec des colonnes via l’argument columns et un mode d’affichage comme show="headings" pour afficher les en-têtes.
  • Les en-têtes se configurent avec tableau.heading(colonne, text=...) pour nommer chaque colonne (ex. Objet, Poids (kg), Valeur (Septims)).
  • Les lignes s’ajoutent avec tableau.insert(parent="", index="end", values=(...)) pour placer des valeurs de colonnes à la fin de la liste.
  • L’option parent="" dans insert signifie que la ligne est ajoutée au niveau racine du Treeview.
  • Dans Tkinter, pack() attache les widgets par empilement et s’utilise avec side pour choisir le bord d’attache (TOP, BOTTOM, LEFT, RIGHT).
  • Ne mélangez jamais pack() et grid() dans le même parent : les deux gestionnaires se disputent le placement et l’interface peut se figer ou planter.

💡 Astuce mémo

pack = empile par bord (TOP/BOTTOM/LEFT/RIGHT) ; grid = grille ; jamais pack+grid dans le même parent.

📖 5. Treeview pour afficher des données

🔑 Notions clés & Définitions

  • Treeview : Widget de la bibliothèque Tk/ttk qui affiche des données sous forme de lignes et colonnes, comme un tableau.
  • grid() : Gestionnaire de géométrie qui place les widgets dans une grille repérée par des indices de lignes et de colonnes.
  • padding : Option de placement qui ajoute de l’espace autour d’un widget pour aérer l’interface.
  • columnspan : Paramètre de grid() qui permet à un widget de s’étendre sur plusieurs colonnes.
  • sticky : Paramètre de grid() qui contrôle l’ancrage ou l’étirement d’un widget dans sa cellule via des directions cardinales.

📝 Points essentiels

  • Pour vos projets, utilisez grid() pour la majorité des mises en page afin d’éviter des comportements incohérents.
  • Dans grid(), la grille est indexée à partir de 0 pour les lignes et les colonnes.
  • padx ajoute une marge horizontale et pady une marge verticale autour du widget.
  • Pour centrer un bouton sous un formulaire à 2 colonnes, utilisez columnspan=2 pour qu’il occupe les colonnes 0 et 1.
  • sticky utilise N, S, E, W pour coller ou étirer le widget, et tk.WE permet de s’étendre sur toute la largeur de la cellule.
  • Quand l’interface devient complexe, créez des conteneurs avec ttk.Frame pour organiser des sous-zones, puis placez les widgets à l’intérieur avec grid().

💡 Astuce mémo

Grille Excel: row/column dès 0; padx/pady = respiration; columnspan = “fusion”; sticky = “coller/étirer” (W/E/N/S).

📖 6. Gestionnaires de géométrie pack et grid

🔑 Notions clés & Définitions

  • pack : Gestionnaire de géométrie qui place les widgets en les empilant selon une direction (side) et en gérant l’expansion via fill et expand.
  • grid : Gestionnaire de géométrie qui place les widgets dans une grille avec des coordonnées row et column.
  • Frame : Conteneur Tkinter utilisé pour regrouper des widgets et créer des zones d’application indépendantes pour pack ou grid.
  • Callback : Fonction appelée automatiquement par un widget lorsqu’un événement survient, par exemple via l’option command d’un Button.
  • Entry : Widget de saisie de texte dont le contenu peut être lu avec get() et modifié via des options avec config().

📝 Points essentiels

  • Règle pratique : évitez de mélanger pack et grid dans le même conteneur, mais vous pouvez utiliser pack au niveau parent puis grid à l’intérieur d’une Frame.
  • Diviser l’interface en Frames permet de créer des zones indépendantes où chaque gestionnaire de géométrie s’applique sans conflit.
  • Placement global typique : pack pour positionner de grandes zones (ex. menu_gauche et zone_centrale) avec side et fill/expand.
  • Placement local typique : grid pour placer des composants à l’intérieur d’une zone (ex. un Label avec row=0 et column=0).
  • Un Button déclenche une action quand l’option command reçoit une référence de fonction (le Callback).
  • Le Callback est exécuté au clic : Tkinter ajoute les parenthèses automatiquement si vous passez le nom de la fonction sans ().

💡 Astuce mémo

pack = empilement, grid = coordonnées; Frame = frontière qui sépare les deux mondes.

📖 7. Règle d’or pack et grid sans mélange

🔑 Notions clés & Définitions

  • Variables globales : En programmation, ce sont des données accessibles depuis n’importe quelle fonction, ce qui facilite l’accès mais rend le code difficile à maîtriser.
  • Code spaghetti : Un code spaghetti est un programme dont la logique est entremêlée, rendant la maintenance et le débogage instables et coûteux.
  • Callback : Un callback est une fonction appelée en réponse à un événement, par exemple le clic sur un bouton.
  • Classe d’application Tkinter : Une classe d’application regroupe la création des widgets et la logique dans un même objet pour éviter la dépendance aux variables globales.
  • Attribut d’instance self.xxx : Un attribut d’instance est une donnée stockée dans un objet via self, permettant d’accéder aux widgets depuis les méthodes.

📝 Points essentiels

  • Dans l’exemple, la fonction afficher_message() lit le texte via champ_nom.get() puis met à jour l’interface avec label_resultat.config(text=...).
  • Quand l’interface grandit (beaucoup de champs, listes et boutons), multiplier les variables globales rend le comportement instable et le débogage difficile.
  • La solution standard présentée consiste à encapsuler l’application dans une classe, comme on le ferait en Java, pour isoler la logique.
  • Dans le constructeur init, les widgets deviennent des attributs d’instance (self.champ, self.label_res) au lieu d’être des variables globales.
  • Le bouton utilise command=self.action : le callback pointe vers une méthode de classe, ce qui donne accès aux widgets via self.
  • Dans la méthode action, l’accès aux widgets se fait avec self (ex. self.champ.get()) puis la mise à jour se fait via self.label_res.config(...).

💡 Astuce mémo

Global = spaghetti ; Classe = self (widgets + logique au même endroit).

📖 8. grid avancé span et sticky

🔑 Notions clés & Définitions

  • Encapsulation de la logique : La logique de l’application est regroupée dans une classe pour isoler le comportement et éviter de disperser le code dans l’entrée du programme.
  • self comme liant : self représente l’instance de la classe et relie les widgets aux méthodes qui les pilotent.
  • Point d’entrée main : Le bloc if name == "main" sert de point d’entrée pour créer la fenêtre, instancier l’application et lancer la boucle Tkinter.
  • Callback lambda : Un callback lambda est une fonction anonyme créée à la volée pour appeler une méthode avec un argument sans exécuter la fonction immédiatement.
  • bind() et event : bind() associe un événement à une méthode, et la méthode reçoit obligatoirement un paramètre event contenant des infos sur l’action.

📝 Points essentiels

  • Le point d’entrée typique crée root avec tk.Tk(), instancie l’application avec MonApp(root), puis démarre root.mainloop().
  • Avec command=, écrire ma_fonction(5) exécute la fonction tout de suite, donc on préfère une lambda pour différer l’appel.
  • La forme command=lambda: self.ajouter_chiffre(1) permet de passer un argument au callback sans déclencher l’action au moment du chargement.
  • bind("<Return>", self.valider) déclenche la méthode quand l’utilisateur appuie sur Entrée sur le widget ciblé.
  • Une méthode appelée par bind() doit accepter un paramètre event, sinon elle ne correspond pas à la signature attendue.
  • event.x et event.y donnent les coordonnées du clic, et event.widget référence le widget qui a subi l’événement.

💡 Astuce mémo

command exécute tout de suite, bind passe event (et event.x/event.y).

📖 9. Structurer avec les Frame conteneurs

🔑 Notions clés & Définitions

  • Objet d’événement Tkinter : Objet transmis par une fonction liée à un événement, contenant des informations sur ce qui s’est produit.
  • messagebox Tkinter : Sous-module Tkinter qui affiche des fenêtres pop-up standards pour informer ou demander confirmation.
  • tk.Toplevel : Classe Tkinter qui crée une fenêtre secondaire au-dessus de la fenêtre racine.
  • ttk.Notebook : Widget Tkinter qui gère une navigation par onglets, chaque onglet affichant une page.
  • ttk.Frame : Conteneur de widgets utilisé comme page ou zone structurante, notamment à l’intérieur d’un Notebook.

📝 Points essentiels

  • Avec bind(), la fonction de rappel reçoit obligatoirement un argument event représentant l’événement déclenché.
  • event.x et event.y donnent les coordonnées du clic dans la zone concernée.
  • event.widget référence l’objet Tkinter qui a subi l’événement.
  • messagebox doit être importé spécifiquement via import tkinter.messagebox as mb pour utiliser mb.askyesno et mb.showinfo.
  • askyesno affiche une boîte Oui/Non et renvoie True si l’utilisateur clique sur Oui.
  • showinfo affiche une boîte d’information (ex. action annulée) sans demander de choix.

💡 Astuce mémo

bind() → callback(event) : l’événement te donne x, y et le widget concerné.

📖 10. Callbacks command et bind avec Event

🔑 Notions clés & Définitions

  • mainloop : La mainloop est la boucle Tkinter qui attend et traite passivement les actions utilisateur jusqu’à la fermeture de l’application.
  • ttk.Notebook : Le ttk.Notebook est un conteneur qui affiche plusieurs pages sous forme d’onglets dans une même fenêtre.
  • Callback command : Un callback command est une fonction associée à un widget via l’argument command pour être appelée lors d’un événement déclenché par l’utilisateur.
  • bind Event : Un bind Event est une association entre un événement (ex. un type d’événement Tk) et une fonction exécutée quand cet événement survient.

📝 Points essentiels

  • Tkinter attend les interactions via la mainloop, qui déclenche ensuite les callbacks associés aux widgets.
  • Avec ttk, on privilégie tkinter.ttk pour des widgets au rendu natif et plus cohérent.
  • La création d’un widget se fait en deux temps : instancier le widget puis le placer avec pack() ou grid().
  • Pour command, on passe la fonction sans parenthèses (ex. command=ma_fonction) pour éviter l’exécution immédiate.
  • Pour bind, on associe un événement sous forme de chaîne (ex. "<Event>") à une fonction appelée au moment où l’événement se produit.
  • Les callbacks peuvent mettre à jour l’interface en modifiant les propriétés d’un widget, par exemple via config(text=...).

💡 Astuce mémo

command = “je donne la fonction”, bind = “je décris l’événement”

📊 Tableaux de synthèse

Procédural vs événementiel

AspectScript procéduralProgrammation événementielle
Contrôle du tempsLe programme est maître du temps (exécute ligne par ligne puis s’arrête)L’utilisateur est maître du temps (l’interface attend)
AttenteSouvent bloquant (ex. input())Programme affiche la fenêtre puis écoute indéfiniment
DéclenchementExécution séquentielle jusqu’à la finRéaction uniquement quand un événement survient (clic, clavier, survol)
Boucle principalePas de boucle d’écoute GUImainloop() tourne en boucle infinie jusqu’à fermeture

⚠️ Pièges & confusions fréquents

  1. Mettre des parenthèses dans command (command=dire_bonjour()) exécute la fonction immédiatement au chargement au lieu d’attendre le clic.
  2. Oublier de placer un widget avec pack() ou grid() : il ne s’affichera jamais à l’écran.
  3. Mélanger pack() et grid() dans le même parent : les gestionnaires se battent et l’interface peut se figer ou planter.
  4. Utiliser command=ma_fonction(5) au lieu de command=lambda: ... : l’argument est évalué trop tôt, avant l’interaction.
  5. Avec bind(), oublier le paramètre event dans la signature de la méthode : la fonction ne correspond pas à la signature attendue.
  6. Confondre tk et ttk : utiliser tk.Button au lieu de ttk.Button alors que le cours recommande ttk pour un rendu natif.
  7. Créer la fenêtre secondaire avec tk.Tk() au lieu de tk.Toplevel() : tk.Tk() est réservé à la fenêtre racine unique.

✅ Checklist Examen

  1. Expliquer la différence de paradigme entre script procédural et programmation événementielle (qui contrôle le temps, rôle des événements).
  2. Décrire le rôle de mainloop() dans une GUI et ce qu’elle fait tant que la fenêtre existe.
  3. Écrire le code minimal Tkinter : import tkinter as tk, root=tk.Tk(), title, geometry, puis root.mainloop().
  4. Choisir et justifier l’usage de ttk (import tkinter as tk + from tkinter import ttk) plutôt que tk classique pour les widgets.
  5. Créer un widget en précisant son parent et ses options (syntaxe ttk.NomDuWidget(parent, option=valeur)).
  6. Rappeler la règle fatale : instancier ne suffit pas, il faut ensuite placer le widget avec pack() ou grid().
  7. Construire un ttk.Treeview : définir columns et show="headings", configurer les en-têtes avec tableau.heading, puis insérer des lignes avec tableau.insert(parent="", index="end", values=...).
  8. Utiliser pack() correctement (side, fill, expand) pour empiler des widgets, et utiliser grid() pour une mise en page en grille indexée à partir de 0.
  9. Appliquer la règle d’or : ne jamais mélanger pack et grid dans le même parent, et utiliser des Frame pour séparer les zones.
  10. Réaliser un layout grid avancé : utiliser padx/pady, columnspan pour fusionner des colonnes, et sticky (N/S/E/W ou tk.WE) pour coller/étirer.
  11. Mettre en place des callbacks : command=ma_fonction sans parenthèses pour Button, et bind("<Event>", callback) pour les événements clavier/souris avec event en paramètre.
  12. Structurer en POO : encapsuler widgets et logique dans une classe (self.xxx), définir le point d’entrée avec if name == "main":, et lancer root.mainloop().
  13. Passer un argument à un callback avec lambda (command=lambda: self.ajouter_chiffre(1)) sans exécuter immédiatement.
  14. Utiliser messagebox : import tkinter.messagebox as mb, distinguer askyesno (renvoie True/False) et showinfo (affiche une info).

Testez vos connaissances

Testez vos connaissances sur Introduction à la programmation GUI avec Tkinter avec 11 questions à choix multiples avec corrections détaillées.

1. Dans une interface graphique, quel rôle joue principalement la boucle mainloop() ?

2. Qu'est-ce que le paradigme événementiel dans le contexte des interfaces graphiques? 1. Une approche où l'interface réagit aux actions de l'utilisateur plutôt que d'exécuter un script linéaire. 2. La méthode d'exécution séquentielle des instructions pour créer une fenêtre. 3. Un mode de programmation basé sur l'exécution automatique de scripts sans interaction. 4. La technique d'utiliser des événements pour détruire automatiquement la fenêtre après affichage.

Faire le QCM →

Révisez avec les flashcards

Mémorisez les concepts clés de Introduction à la programmation GUI avec Tkinter avec 9 flashcards interactives.

Paradigme événementiel — rôle ?

Réagit aux actions utilisateur plutôt que d'exécuter un script linéaire.

Programmation événementielle: définition

Interface réagit aux actions utilisateur.

mainloop — fonction ?

Boucle d’écoute infinie qui maintient l’interface active.

Voir les flashcards →

Cours similaires

Crée tes propres fiches de révision

Importe ton cours et l'IA génère fiches, QCM et flashcards en 30 secondes.

Générateur de fiches