Aller au contenu principal

Découvrir Tkinter

Créer sa première fenêtre avec des widgets de base

Notions théoriques

Tkinter (de l'anglais Tool kit interface) est la bibliothèque standard de Python pour créer des interfaces graphiques (GUI).

info
  • Sous Windows, Tkinter est inclus avec Python, ce qui évite toute installation supplémentaire.
  • Sous MacOS, il est généralement inclus, mais il peut être nécessaire d'installer python-tk via Homebrew.
  • Sous Linux, il faut installer le paquet python3-tk.

Créer une interface avec Tkinter repose toujours sur ces étapes fondamentales :

  1. Importer le module
  2. Créer la fenêtre principale ( Tk() )
  3. Ajouter des widgets (boutons, étiquettes, zones de texte, cases à cocher…)
  4. Organiser les widgets avec un gestionnaire de géométrie (pack, grid ou place)
  5. Écrire une fonction puis la passer en paramètre à un widget (ex : bouton)
  6. Lancer la boucle principale (mainloop)
import tkinter as tk

La classe principale s'appelle Tk.
Presque tous les programmes Tkinter commencent ainsi :

fenetre = tk.Tk()
fenetre.title("Ma première fenêtre")
fenetre.geometry("400x300") # largeur × hauteur
astuce

En Python, la syntaxe fenetre = tk.Tk() crée une instance de la classe Tk du module tkinter.

Cette instance représente la fenêtre principale (dans la variable fenetre) de l'application graphique.

En Python, on ne met pas le mot-clé new comme en PHP, Java ou C++ pour créer un nouvel objet. L'appel tk.Tk() instancie un nouvel objet de la classe Tk et retourne cette instance. L'affectation fenetre = tk.Tk() signifie donc que la variable fenetre référence cet objet nouvellement créé.

lors de l’appel à une classe dans une instruction pour créer un objet, il faut toujours indiquer des parenthèses (même si aucun argument n’est transmis).

On peut donc dire que fenetre = tk.Tk() est l'équivalent conceptuel de fenetre = new tk.Tk() dans un langage comme Java, mais en Python, on ne met pas explicitement new.

La création d'objet se fait simplement en appelant la classe comme une fonction :

  • fenetre = tk.Tk() crée une nouvelle fenêtre principale Tkinter.
  • Il n'y a pas de new en Python, mais le but est le même : création d'une instance.

Les widgets les plus courants

  • Label → affiche du texte ou une image
  • Button → bouton cliquable
  • Entry → zone de saisie d’une ligne
  • Text → zone de saisie multiligne
  • Checkbutton → case à cocher
  • Radiobutton → bouton radio (choix exclusif)
  • Frame → conteneur invisible pour regrouper des widgets

3 gestionnaires de widgets

Tkinter propose 3 façons d’organiser les widgets dans une fenêtre ou un conteneur (Frame) :

  • pack()
  • grid()
  • place()

1. Le gestionnaire pack

Place les widgets les uns après les autres (haut → bas par défaut)

label.pack()
bouton.pack()

Options utiles : side, fill, expand, padx, pady

astuce

pack() est le plus simple à utiliser pour des interfaces basiques.

pack() est le gestionnaire de widgets que nous allons utiliser.

2. Le gestionnaire grid

Tableau avec lignes et colonnes

label.grid(row=0, column=0, padx=10, pady=5)
entry.grid(row=0, column=1)

Options utiles : row, column, padx, pady, columnspan, rowspan, sticky

astuce

grid() est plus flexible que pack() et permet de créer des mises en page plus complexes.

2. Le gestionnaire place

Position absolue en pixels (x,y) (peu recommandé sauf cas très précis)

Options utiles : x, y, width, height, relx, rely, relwidth, relheight

astuce

place() permet un positionnement précis mais est moins flexible et plus difficile à maintenir.

attention

Ne jamais mélanger pack() et grid() dans le même conteneur (même fenêtre ou même Frame). Cela provoque une erreur.


Associer une action à un bouton (command)

La plupart du temps on écrit une fonction puis on la passe en paramètre command=

def saluer():
print("Bonjour !")

bouton = tk.Button(fenetre, text="Dire bonjour", command=saluer)
info

La fonction passée à command ne doit pas avoir de parenthèses : command=saluer et non command=saluer()


Modifier un widget après sa création

On utilise la méthode .config() ou on accède directement aux propriétés :

label.config(text="Nouveau texte", fg="darkblue", bg="lightyellow")
label["font"] = ("Helvetica", 14, "bold")

Variables Tkinter (pour lier widgets et données)

Pour que les widgets Entry / Checkbutton / Radiobutton / Scale restent synchronisés avec une valeur Python :

  • StringVar(), IntVar(), DoubleVar(), BooleanVar()

Exemple classique :

nom = tk.StringVar()
entry = tk.Entry(fenetre, textvariable=nom)
print(nom.get()) # lecture
nom.set("Alice") # écriture
remarque

Les variables Tkinter permettent d’éviter de devoir récupérer la valeur à chaque clic sur un bouton.


Exemple pratique

Voici un exemple minimaliste qui utilise .pack().

.pack() est la méthode de placement la plus simple : les widgets s'empilent les uns sous les autres automatiquement.

import tkinter as tk

# Création de la fenêtre principale
fenetre = tk.Tk()
fenetre.title("Exemple pratique")

# Création d'un texte (Label)
etiquette = tk.Label(
fenetre,
text="Bonjour à tous !",
font=("Arial",
16
)
)
etiquette.pack(padx=20, pady=20) # padx/pady ajoute un peu de marge

# Lancement de la boucle d'événements
fenetre.mainloop()
info

La classe Label de Tkinter attend que les options comme text, font, pady soient passées en arguments nommés.

  • fenetre est le seul argument attendu (le parent du widget).
  • text, font, pady doivent être passés explicitement par leur nom.

Ce que ce code réalise :

  1. L'import de la bibliothèque.
  2. La création de la fenêtre fenetre (tk.Tk()).
  3. La création d'un widget simple (Label).
  4. L'utilisation de .pack() pour afficher le widget.
  5. La boucle infinie (mainloop) indispensable pour que la fenêtre reste ouverte.

Test de mémorisation/compréhension


Quel est le rôle principal de la méthode mainloop() dans une application Tkinter ?


Quel argument doit obligatoirement être passé en premier lors de la création d’un widget Tkinter ?


Quelle méthode permet de modifier les propriétés d’un widget après sa création ?


Quelle est la syntaxe correcte pour créer une fenêtre principale Tkinter ?


Quel widget Tkinter permet de saisir une seule ligne de texte ?


Quelle option du gestionnaire pack() permet d’ajouter de l’espace autour d’un widget ?


Comment doit-on passer une fonction à l’option command d’un bouton Tkinter ?


Quel type de variable Tkinter utiliser pour lier une zone de texte Entry à une variable Python ?


Quelle méthode de gestion de placement est recommandée pour des interfaces simples ?


Quel widget Tkinter permet d’afficher du texte statique ?


Quelle est la bonne syntaxe pour définir la taille d’une fenêtre Tkinter à 400 pixels de large et 300 de haut ?


Quel widget Tkinter permet de regrouper d’autres widgets sans affichage visible ?


Quelle est la conséquence de ne pas appeler mainloop() dans un programme Tkinter ?


Quelle méthode permet d’ajouter un widget à la fenêtre en utilisant le gestionnaire pack() ?


Quel est le rôle du widget Checkbutton dans Tkinter ?


Quel est l’avantage principal d’utiliser les variables Tkinter (StringVar, IntVar, etc.) ?


Quelle est la syntaxe correcte pour créer un Label avec du texte, une police et un padding vertical ?


Quelle est la distinction principale entre les widgets `Entry` et `Text` ?


Quel type de variable Tkinter faut-il utiliser pour lier un widget `Entry` à une donnée Python ?


Quelle méthode des variables Tkinter (comme `StringVar`) est utilisée pour récupérer la valeur actuelle ?


Quelle est le comportement par défaut du gestionnaire `pack()` lorsqu'il place les widgets ?


Quel widget permet un 'choix exclusif' parmi plusieurs options ?


Quel est le rôle principal du widget `Frame` ?


Quel module spécifique faut-il importer pour utiliser `messagebox.showinfo` ?


Quelle est la fonction de la méthode `mainloop()` dans un script Tkinter ?



TP pour réfléchir et résoudre des problèmes

1. Créer un dossier tp-tkinter-demo et y ajouter un fichier main.py

mkdir tp-tkinter-demo
cd tp-tkinter-demo
touch main.py

2. Créer un environnement virtuel Python et l’activer :

python -m venv venv
source venv/bin/activate # Sur Windows : venv\Scripts\activate
attention

Sous MacOS, ne pas utiliser Fish mais Bash ou Zsh pour activer l’environnement virtuel.

3. Installer Tkinter si nécessaire :

Pour tester si Tkinter est bien installé, lancez la commande suivante dans un terminal :

python -m tkinter

Si une petite fenêtre Tkinter s’ouvre, c’est que tout est bon.

Si l'erreur ModuleNotFoundError: No module named '_tkinter's'affiche

Pour résoudre l'erreur ModuleNotFoundError: No module named '_tkinter', il suffit d'installer tkinter dans votre environnement Python, avec la commande :

# Sur Debian/Ubuntu
sudo apt-get install python3-tk
# Sur MacOS avec Homebrew
brew install tcl-tk
brew install python-tk
# Sur Windows, Tkinter est inclus avec Python

4. Ouvrir main.py avec Visual Studio Code et c pour importer tkinter et créer la fenêtre principale

import tkinter as tk

# --------------------------------------
# Création de la fenêtre principale
# --------------------------------------
fenetre = tk.Tk()
fenetre.title("TP Tkinter - Démo")
fenetre.geometry("400x250")



fenetre.mainloop()

Le fichier main.py sera rempli plus tard.

5. Lancer le script pour vérifier que la fenêtre s’affiche correctement :

python main.py

6. Ajouter une étiquette (Label) avec le texte "Bienvenue dans Tkinter !"

Insérez le code suivant avant fenetre.mainloop() :

etiquette = tk.Label(
fenetre,
text="Bienvenue dans Tkinter !",
font=("Arial", 16),
pady=20
)
etiquette.pack()

remarque

La propriété pady ajoute un espace vertical autour de l’étiquette.

7. Ajouter une zone de saisie (Entry) pour que l’utilisateur puisse entrer son prénom

Insérez le code suivant avant fenetre.mainloop() :

saisie = tk.Entry(
fenetre,
width=30,
font=("Arial", 14),
justify="center"
)
saisie.pack(pady=10)
remarque

La propriété justify="center" centre le texte dans la zone de saisie.

8. Ajouter un bouton (Button) avec le texte "Valider" qui affiche une boîte de dialogue de bienvenue personnalisée

Insérez le code suivant avant fenetre.mainloop() :

def saluer():
prenom = saisie.get().strip()
if prenom == "":
messagebox.showwarning("Attention", "Veuillez entrer un prénom !")
return
tk.messagebox.showinfo("Bienvenue", f"Bonjour {prenom}, bienvenue dans Tkinter !")

bouton = tk.Button(
fenetre,
text="Valider",
font=("Arial", 12),
width=15,
command=saluer
)
bouton.pack(pady=15)

attention

En Python, la fonction saluer() peut accéder directement à la variable saisie sans qu’il soit nécessaire de la lui passer en paramètre, car saisie est définie dans la même portée globale que la fonction :

  • La variable saisie est créée dans le même bloc de code que la fonction saluer(), donc elle est visible et accessible à l’intérieur de cette fonction.
  • En Python, les fonctions peuvent accéder aux variables définies dans leur environnement extérieur (portée englobante), ce qui évite de devoir passer explicitement ces variables en argument.
  • Cela simplifie le code et évite de devoir modifier la signature de la fonction pour transmettre des widgets ou autres objets déjà accessibles.

Ainsi, dans ce cas, saluer() utilise directement saisie.text() pour récupérer le texte saisi, sans que saisie ait besoin d’être un paramètre de la fonction.

C’est une pratique courante en programmation Python avec des interfaces graphiques, où les widgets sont souvent créés dans un même scope et utilisés dans des fonctions de rappel (callbacks) sans passage explicite d’arguments.

remarque

La fonction saluer() récupère le prénom entré, vérifie qu’il n’est pas vide, puis affiche une boîte de dialogue avec un message de bienvenue.

N’oubliez pas d’importer messagebox au début du fichier :

from tkinter import messagebox

9. Tester le programme complet en lançant python main.py :

  • Saisir un prénom (ex. : Pierre ROF) et cliquer sur le bouton Valider.
  • Une boîte de dialogue, avec le message de bienvenue, doit s'afficher.

Corrigé

Une solution possible