Skip to content

Programmation GUI en Python

Programmation d’interfaces graphiques (GUI) en Python (tkinter)

Section titled “Programmation d’interfaces graphiques (GUI) en Python (tkinter)”

Python offre plusieurs bibliothèques pour créer des Interfaces Utilisateur Graphiques (GUI). Voici quelques options populaires :

  • tkinter : (anciennement Tkinter en Python 2) L’interface Python standard et intégrée au toolkit GUI Tcl/Tk. Elle est multiplateforme et relativement facile à prendre en main. Ce chapitre se concentre sur tkinter.
  • PyQt / PySide : Liaisons pour le puissant framework Qt. Offre une large gamme de widgets et de fonctionnalités modernes. Souvent utilisé pour les applications de bureau complexes.
  • Kivy : Une bibliothèque open-source pour développer des applications multi-touch. Convient aux interfaces utilisateur modernes, aux jeux et au développement mobile.
  • wxPython : Liaisons pour la bibliothèque C++ wxWidgets. Un autre toolkit multiplateforme mature.
  • Frameworks Web (avec wrappers) : Utilisation de frameworks comme Flask/Django avec des outils comme PyWebView ou des wrappers de type Electron pour créer des applications de bureau avec des technologies web.

tkinter offre un moyen simple de construire des applications GUI directement avec Python. Il encapsule le toolkit Tcl/Tk, rendant ses composants disponibles sous forme de classes Python.

Étapes de base pour créer une application tkinter :

  • Importez le module tkinter (généralement importé sous le nom tk).
  • Créez la fenêtre principale de l’application (une instance de tk.Tk).
  • Ajoutez des widgets (boutons, étiquettes, champs de saisie, etc.) à la fenêtre principale ou à d’autres widgets conteneurs (comme les Frame).
  • Configurez les propriétés et la disposition des widgets à l’aide des gestionnaires de géométrie (pack, grid, place).
  • Définissez des gestionnaires d’événements (fonctions à appeler lorsque des boutons sont cliqués, etc.).
  • Démarrez la boucle d’événements principale de tkinter (mainloop()) pour rendre la fenêtre interactive et réactive aux actions de l’utilisateur.
#!/usr/bin/env python3
import tkinter as tk
# 1. Créer la fenêtre principale
root = tk.Tk()
root.title("Simple Tkinter App") # Définir le titre de la fenêtre
root.geometry("300x150") # Définir la taille initiale de la fenêtre (largeur x hauteur)
# 2. Ajouter des widgets (exemple : une étiquette)
my_label = tk.Label(root, text="Hello, Tkinter!")
my_label.pack(pady=20) # Utiliser le gestionnaire de géométrie pack avec un espacement
# 3. Ajouter un bouton avec une action
def on_button_click():
print("Button clicked!")
my_label.config(text="Button was clicked!")
my_button = tk.Button(root, text="Click Me", command=on_button_click)
my_button.pack()
# 4. Démarrer la boucle d'événements principale
root.mainloop()
# Le code après mainloop() ne s'exécute qu'après la fermeture de la fenêtre.

L’exécution de ce script créera une petite fenêtre intitulée “Simple Tkinter App”, contenant le texte “Hello, Tkinter!” et un bouton “Click Me”. Cliquer sur le bouton affichera un message dans la console et modifiera le texte de l’étiquette.

Les widgets sont les éléments constitutifs d’une interface graphique tkinter (boutons, zones de texte, étiquettes, etc.). Chaque widget est représenté par une classe.

Widgets couramment utilisés :

Classe de Widget / ModuleDescription
TkLa fenêtre principale (racine) de l’application.
ToplevelCrée des fenêtres supplémentaires et distinctes.
FrameUn widget conteneur utilisé pour regrouper et organiser d’autres widgets.
LabelAffiche du texte statique ou des images.
ButtonUn bouton cliquable qui peut déclencher un appel de fonction (command).
EntryUn champ de saisie de texte sur une seule ligne.
TextUne zone de saisie et d’affichage de texte multi-lignes.
CheckbuttonUne case à cocher permettant la sélection/désélection.
RadiobuttonPermet la sélection d’une option parmi un groupe (liées par une variable partagée).
ListboxAffiche une liste d’éléments parmi lesquels l’utilisateur peut choisir.
ScrollbarAjoute une capacité de défilement aux widgets comme Listbox, Text, Canvas.
MenuCrée des barres de menu et des menus contextuels.
ScaleUn widget de curseur pour sélectionner une valeur dans une plage.
CanvasUn widget polyvalent pour dessiner des formes, des lignes, du texte, des images et intégrer d’autres widgets.
SpinboxUn widget Entry avec des flèches haut/bas pour sélectionner une valeur dans une plage.
LabelFrameUn Frame avec une bordure visible et une étiquette de texte.
PanedWindowUn conteneur qui gère des volets redimensionnables par l’utilisateur.
MessageSimilaire à Label mais conçu pour les messages texte multi-lignes.
messagebox (module)tkinter.messagebox fournit des fonctions pour les boîtes de dialogue standard (info, avertissement, erreur, demander oui/non, etc.).

Les widgets possèdent de nombreuses options (attributs) qui contrôlent leur apparence et leur comportement. Celles-ci peuvent être définies lors de la création ou modifiées ultérieurement à l’aide de la méthode config() ou configure() (ou de l’accès de type dictionnaire widget['option'] = value).

Les options courantes incluent :

  • text : Le texte affiché sur le widget (Label, Button, etc.).
  • textvariable : Une variable tkinter (StringVar, IntVar, etc.) liée au texte/valeur du widget. Les modifications de la variable mettent à jour le widget, et vice versa (pour Entry, Checkbutton, Radiobutton, Scale).
  • command : Une fonction à appeler lorsque le widget est activé (par exemple, un clic sur un bouton).
  • width, height : Taille du widget (les unités dépendent du widget, souvent des unités de texte ou des pixels).
  • bg (ou background), fg (ou foreground) : Couleurs d’arrière-plan et de texte/premier plan.
  • font : Spécifie la police (par exemple, ('Arial', 16, 'italic')).
  • relief : Style de bordure (flat, raised, sunken, groove, ridge).
  • borderwidth (ou bd) : Largeur de la bordure.
  • state : État du widget (normal, disabled, readonly).
  • anchor : Où positionner le contenu dans l’espace du widget (par exemple, tk.N, tk.S, tk.E, tk.W, tk.CENTER).
  • padx, pady : Rembourrage interne (espace entre le contenu et la bordure).
  • image : Affiche une image (nécessite un objet PhotoImage ou BitmapImage).

Exemple utilisant les options :

import tkinter as tk
root = tk.Tk()
root.title("Widget Options")
# Label with specific font and color
label = tk.Label(
root,
text="Styled Label",
font=("Helvetica", 16, "italic"),
fg="blue",
bg="lightgrey",
padx=10,
pady=10,
relief=tk.RAISED,
borderwidth=2
)
label.pack(pady=10)
# Button initially disabled
button = tk.Button(root, text="Disabled Button", state=tk.DISABLED)
button.pack(pady=5)
# Function to enable the button
def enable_button():
button.config(state=tk.NORMAL)
button['text'] = "Enabled!"
enabler_button = tk.Button(root, text="Enable Other Button", command=enable_button)
enabler_button.pack(pady=5)
root.mainloop()

Les gestionnaires de géométrie contrôlent la position et la taille des widgets au sein de leur conteneur parent. tkinter propose trois gestionnaires principaux :

  • pack() : Organise les widgets en blocs. Les widgets sont “emballés” séquentiellement le long des côtés (top, bottom, left, right) de l’espace restant dans le conteneur. Simple pour les mises en page de base mais peut devenir complexe pour des designs élaborés.
  • grid() : Dispose les widgets dans une grille de lignes et de colonnes, semblable à un tableau. Offre un contrôle plus précis sur le placement et l’alignement. Très flexible pour les mises en page complexes.
  • place() : Permet de positionner les widgets en utilisant des coordonnées absolues (x, y) ou des positions/tailles relatives à l’intérieur du conteneur. Moins couramment utilisé pour la mise en page générale car il s’adapte mal au redimensionnement de la fenêtre ou aux changements de contenu, mais utile pour des besoins de positionnement spécifiques.

Important : Vous ne devez pas mélanger pack() et grid() au sein du même conteneur parent. Utilisez l’un ou l’autre de manière cohérente pour les widgets directement à l’intérieur d’un Frame ou d’une Window spécifique. Cependant, vous pouvez utiliser pack à l’intérieur d’un Frame et grid à l’intérieur d’un autre Frame dans la même fenêtre.

label1 = tk.Label(root, text="Top", bg="red")
label1.pack(side=tk.TOP, fill=tk.X) # Remplir horizontalement
label2 = tk.Label(root, text="Left", bg="blue")
label2.pack(side=tk.LEFT, fill=tk.Y) # Remplir verticalement
label3 = tk.Label(root, text="Center", bg="green")
label3.pack(expand=True, fill=tk.BOTH) # S'étendre pour remplir l'espace restant
entry1 = tk.Entry(root)
entry1.grid(row=0, column=1, padx=5, pady=5)
label1 = tk.Label(root, text="Label 1:")
label1.grid(row=0, column=0, sticky=tk.E) # Aligner à droite
entry2 = tk.Entry(root)
entry2.grid(row=1, column=1, padx=5, pady=5)
label2 = tk.Label(root, text="Longer Label 2:")
label2.grid(row=1, column=0, sticky=tk.E)
button = tk.Button(root, text="Submit")
# S'étendre sur 2 colonnes, ajouter un espacement, coller au coin inférieur droit de la cellule
button.grid(row=2, column=0, columnspan=2, pady=10, sticky=tk.SE)
button1 = tk.Button(root, text="Absolute Position")
button1.place(x=50, y=50)
button2 = tk.Button(root, text="Relative Position")
# Placer à 70% de la largeur, 70% de la hauteur par rapport à la taille du parent
button2.place(relx=0.7, rely=0.7, anchor=tk.CENTER) # ancre centre

Les interfaces graphiques répondent aux interactions de l’utilisateur (événements) telles que les clics de bouton, les pressions de touches, les mouvements de souris. tkinter utilise des fonctions de rappel (callbacks) et la liaison d’événements (event binding).

  • Option command : De nombreux widgets (comme Button, Checkbutton, Radiobutton) ont une option command qui spécifie une fonction à appeler lorsque le widget est activé.
  • Méthode bind() : Offre un moyen plus général de lier des fonctions Python (gestionnaires d’événements) à des événements spécifiques (comme <Button-1> pour un clic gauche de la souris, <KeyPress> pour une pression de touche, <Enter> pour l’entrée de la souris dans la zone du widget) sur n’importe quel widget.

Exemple utilisant bind() :

import tkinter as tk
def handle_click(event):
# L'objet 'event' contient des détails comme les coordonnées (event.x, event.y)
print(f"Left mouse button clicked at ({event.x}, {event.y})")
def handle_keypress(event):
print(f"Key pressed: '{event.char}' (Key code: {event.keycode})")
root = tk.Tk()
root.geometry("300x200")
frame = tk.Frame(root, width=200, height=100, bg="lightblue")
# Lier l'événement de clic gauche de la souris (<Button-1>) sur le cadre
frame.bind("<Button-1>", handle_click)
frame.pack(pady=20)
entry = tk.Entry(root)
# Lier tout événement de pression de touche (<KeyPress>) sur le widget d'entrée
entry.bind("<KeyPress>", handle_keypress)
entry.pack(pady=10)
entry.focus_set() # Donner le focus au champ de saisie pour que les pressions de touches soient capturées
root.mainloop()
  • Documentation Tkinter : https://docs.python.org/3/library/tkinter.html
  • Ressources de tutoriels Tkinter (par exemple, TkDocs, ZetCode Tkinter).
  • Envisagez d’explorer les widgets thématiques de tkinter.ttk pour une apparence plus moderne.