Tutoriel Tkinter Python
2024-10-30programmation, Python
Prérequis : Il faut être un peu à l'aise avec le Python, au moins les variables, fonctions, manipulation des chaînes de caractères. Si ce n'est pas le cas, France-IOI propose une introduction ludique au Python.
Tkinter est une bibliothèque d'interface graphique, qui permet de créer des fenêtres sous Linux, Windows et Mac. C'est une des plus simples à utiliser en Python. Seulement elle est un peu vieille et trop peu intuitive, d'où ce tutoriel qui peut servir de mini-référence.
Pour aller plus loin : TkDocs Tutorial (en anglais)
Ce tutoriel est disponible en PDF. Le code source et les commandes utilisées pour générer le PDF sont disponibles dans ce dépôt Git.
#Code de base
Créer une fenêtre vide :
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.mainloop()
Ajouter des boutons dans la fenêtre :
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
bt1 = ttk.Button(root, text="Bonjour")
bt1.grid(column=0, row=0)
bt2 = ttk.Button(root, text="Au revoir")
bt2.grid(column=1, row=0)
root.mainloop()
#Positionnement
On peut changer le nombre de colonnes ou de lignes occupées par un widget en ajoutant les paramètres columnspan
ou rowspan
en plus de column
et row
.
Pour coller un widget au bord de la grille, on peut ajouter sticky
:
bt2.grid(column=1, row=0, sticky=(tk.W, tk.N))
sticky
prend une liste de 0 à 4 éléments parmi :
tk.E
: East = droitetk.N
: North = hauttk.S
: South = bastk.W
: West = gauche
#Redimensionner la fenêtre
Il faut indiquer quelles lignes et colonnes doivent changer de taille quand la fenêtre change de taille.
Dans cet exemple, ce sont la ligne 1 et la colonne 0.
root.rowconfigure(1, weight=1)
root.columnconfigure(0, weight=1)
On peut appeler plusieurs fois ces fonctions pour choisir plusieurs lignes et colonnes, et changer les weight
pour modifier les proportions.
#Widgets
Tous les widgets doivent être positionnés avec grid
, de la même manière que ci-dessus.
Sans ça, ils ne seront pas affichés !
#Label
Juste du texte.
label = ttk.Label(root, text="Je suis un texte. Wow.")
On peut aussi modifier le texte plus tard :
label_text = tk.StringVar()
label["textvariable"] = label_text
label_text.set("Le nouveau texte. Tout ça pour ça !")
#Bouton
Un bouton qu'on peut cliquer.
def onclick():
print("On a cliqué")
bt = ttk.Button(root, text="Cliquez-moi", command=onclick)
#Image
Un bouton ou un label peut afficher une image :
img = tk.PhotoImage(file='image.png')
label["image"] = img
#Entrée de texte
Boîte dans laquelle on peut écrire une ligne de texte.
text = tk.StringVar()
entry = ttk.Entry(root, textvariable=text)
Plus tard, on peut récupérer le texte :
print("L'utilisateur a écrit :", text.get())
#Entrée de texte multiligne
Zone dans laquelle on peut écrire du texte en plusieurs lignes.
text = tk.Text(root)
Il y a plusieurs méthodes pour interagir avec le texte :
print(text.get("1.0", "end")) # obtenir tout le texte
print(text.get("2.0", "8.0")) # le texte de la ligne 2 à la ligne 8
text.replace("1.0", "end", "le nouveau texte") # remplacer du texte
text.insert("1.0", "le nouveau texte") # insérer du texte
text.insert("1.0 +42 chars", "le nouveau texte")
text.insert("end -3 lines", "le nouveau texte")
Pour mettre en forme certaines parties du texte, on peut utiliser des tags :
text.tag_configure("fond_rouge", background="#ffaaaa")
text.tag_configure("insistance", foreground="#008800", underline=True)
text.insert("1.0", "ce texte sera sur fond rouge", "fond_rouge")
text.tag_add("insistance", "1.3", "1.8")
Liste de tous les styles possibles.
#Barre de défilement
Certains widgets (Text
) peuvent défiler avec la molette, mais pour afficher la barre de défilement il faut un widget supplémentaire.
scroll = ttk.Scrollbar(root, orient=tk.VERTICAL, command=mon_widget_qui_défile.yview)
scroll.grid(column=1, row=0, sticky=(tk.N, tk.S, tk.E, tk.W))
mon_widget_qui_défile.configure(yscrollcommand=scroll.set)
#Cadre
Un cadre qui peut avoir une bordure et contenir d'autres widgets.
frame = ttk.Frame(root, borderwidth=5, relief="ridge", width=200, height=100)
Les options ne sont pas obligatoires.
Le cadre contient ses propres lignes et colonnes.
Pour placer des widgets dedans, il suffit de remplacer root
par frame
en les créant.
#Barre de menus
La barre de menus en haut de la fenêtre.
root.option_add('*tearOff', False)
menubar = tk.Menu(root)
root['menu'] = menubar
menu_file = tk.Menu(menubar)
menu_edit = tk.Menu(menubar)
menubar.add_cascade(menu=menu_file, label='Fichier')
menubar.add_cascade(menu=menu_edit, label='Édition')
menu_file.add_command(label='Ouvrir', command=on_open)
#Canevas
Le canevas est une zone de dessin.
canvas = tk.Canvas(root, background='white')
On peut y dessiner des formes :
canvas.create_line(x1, y1, x2, y2)
canvas.create_line(x1, y1, x2, y2, fill="red", width=3, dash=6)
canvas.create_rectangle(x1, y1, x2, y2, fill="red", outline="blue")
canvas.create_oval(x1, y1, x2, y2, fill="red", outline="blue")
#Événements
Quand il se passe quelque chose sur un widget, un événement est généré. On peut écouter les événements de certains types, c'est-à-dire lancer une fonction quand l'action se produit.
Par exemple, on affiche des informations quand une touche du clavier est relâchée dans la zone de texte :
text = tk.Text(root)
def onrelease(event):
print("On a frappé le clavier !")
print(event)
text.bind("<KeyRelease>", onrelease)
On peut aussi utiliser les infos contenues dans l'événement, par exemple event.keycode
.
#Liste des événements
- Souris
ButtonPress
: clic enfoncé d'un bouton de la sourisButton-1
: commeButtonPress
mais seulement pour le clic gaucheButton-2
: commeButtonPress
mais seulement pour le clic moletteButton-3
: commeButtonPress
mais seulement pour le clic droitButtonRelease
: clic relâché d'un bouton de la sourisDouble-1
: double-clic gaucheDouble-3
: double-clic droitEnter
: le pointeur de la souris entreLeave
: le pointeur de la souris sortMotion
: le pointeur de la souris bouge dedansB1-Motion
: commeMotion
mais avec le clic gauche enfoncéB2-Motion
: commeMotion
mais avec le clic molette enfoncéB3-Motion
: commeMotion
mais avec le clic droit enfoncé
- Clavier
KeyPress
: appui d'une touche du clavierKeyRelease
: relâche d'une touche du clavier
- Widget
Configure
: le widget est crééExpose
: le widget est affiché ou réaffichéFocusIn
: le widget reçoit le focusFocusOut
: le widget pert le focus
#Dialogues
On peut ouvrir des fenêtres pour dire ou demander des choses.
#Fichiers
Demander où enregistrer un fichier, quel fichier ouvrir, choisir un dossier.
from tkinter import filedialog
filetypes = [
("Texte", "*.txt"),
("Image PNG", "*.png"),
("Autre", "*.*")
]
chemin = tk.filedialog.asksaveasfilename(filetypes=filetypes)
print(chemin)
On peut remplacer asksaveasfilename
par askopenfilename
ou askdirectory
.
#Couleur
Demander de choisir une couleur.
from tkinter import colorchooser
color = colorchooser.askcolor(initialcolor='black')
print(color)
On peut aussi indiquer la couleur initiale avec sa notation hexadécimale "#000000"
.