Utiliser Tkinter pour donner des interfaces à vos scripts…
Dans ce tutoriel, vous allez apprendre pas à pas les bases de tkinter en Python : créer une fenêtre, y ajouter du texte, des boutons, et autres, mais aussi l’organiser à l’aide de boites et de grilles.
Qu’est ce que Tkinter ?
Tkinter (ou ToolKit Interface) est une library Python permettant de donner une interface graphique à vos scripts Python et ainsi les rendre plus agréables à utiliser, qu’ils s’agisse de simulateurs, de programmes de calcul ou de mini jeux textuels par exemple.
Il est important de noter que Tkinter n’est pas disponible sur la Numworks ou autre calculatrice utilisant Python, mais est par contre utilisable sous Windows, Linux macOS et même sur Android en utilisant Pydroid
Installer Tkinter
Tkinter est inclus avec Python 3 sous Windows, Linux ou macOS, vous n’aurez donc normalement pas à vous soucier de devoir l’installer en plus.
Au début de votre script, vous aurez simplement à taper les lignes suivantes afin d’importer la bibliothèque tkinter :
from tkinter import * import tkinter as tk
Maintenant que l’on a spécifié que l’on allait utiliser cette bibliothèque, on peut commencer à mettre en place notre fenêtre.
Création de la fenêtre
C’est dans cette fenêtre que tous les éléments vont apparaître.
Pour commencer, nous allons créer une fenêtre. Pour cela une ligne suffit:
fenetre = Tk()
Lorsque l’on exécute le script rien ne se passe: il faut spécifier au script que l’on veut faire apparaître la fenêtre. Pour cela, entrer la ligne suivante à la fin de votre script.
fenetre.mainloop()
Il est important que cette ligne reste la dernière de votre programme, car tout ce qui sera écrit après cette ligne n’apparaîtra pas dans la fenêtre
On obtient alors normalement le résultat suivant :
Maintenant que l’on a créé cette fenêtre, on peut la personnaliser: lui donner un nom, des dimensions, une couleur de fond etc…
fenetre.title("Ma permière fenêtre Tkinter!") fenetre.geometry("1080x720") fenetre.config(bg="#d1fdff")
Les dimensions seront écrites sous la forme "largeurxhauteur"
La couleur peut être spécifiée de deux manières différentes:
- Avec le nom de la couleur en anglais (ex.
bg="grey"
) - En utilisant sa notation en héxadécimal, comme dans l’exemple donné ci-dessus. Il est possible de trouver des couleurs en héxadécimal à l’aide de cet outil
On obtient alors ceci :
Il est également possible de personnaliser l’icône de la fenêtre.
Pour cela, il vous faudra une image au format .ico
. On peut convertir des images au format .png
en .ico
à l’aide d’un convertisseur en ligne
Une fois que vous avez votre icône, placez la dans le même dossier que votre script, et entrez la ligne suivante (en remplaçant "logo.ico"
par "lenomdevotreicone.ico"
)
fenetre.iconbitmap("logo.ico")
Il est aussi possible de définir la taille minimale de la fenêtre:
fenetre.minsize(500,500)
On a donc appris à personnaliser notre fenêtre tkinter… mais elle reste tout de même bien vide. Nous allons donc voir comment ajouter des éléments à cette fenêtre.
Ajouter du texte
Pour ajouter du texte sur notre interface, on va utiliser une instance nommée Label
titre = Label(fenetre, text="Voici un exemple de Label en police consolas et en taille 20", font=("Consolas",20), bg="#d1fdff", fg="black") soustitre = Label(fenetre, text="Voici un exemple de Label en police Helvetica et en taille 15", font=("Helvetica",15), bg="#d1fdff", fg="black")
On remarque que l’on peut personnaliser différents aspects du Label:
- La boîte dans laquelle il se trouve (cette notion sera abordée un peu plus loin)
- Le texte qu’il renferme (
text
) - Sa police et taille d’écriture (
font
) - Son arrière plan (
bg
pour background ) - Sa couleur de police (
fg
pour foreground )
Si l’on exécute le script, on s’aperçoit que le texte ne s’affiche pas: là aussi, il faut spécifier qu’il faut l’afficher à l’aide de l’instruction .pack()
. Il sera nécessaire d’appeler tout nouvel élément que l’on créé de cette manière.
titre.pack() soustitre.pack()
Les différents éléments que vous allez incorporer à votre fenêtre apparaîtront dans l’ordre dans lequel vous allez les appeler à l’aide de .pack()
, ici, titre
sera donc au dessus de soustitre
.
Il est possible de donner une marge à notre texte en utilisant pady
et padx
. Par exemple, l’instruction suivante donne une marge de 45 des deux côtés en hauteur
titre.pack(pady=45)
On peut aussi spécifier au texte de prendre toute la place possible en utilisant expand
comme ceci:
titre.pack(expand=YES)
Ajouter des boutons
Maintenant que l’on sait faire apparaître du texte sur notre fenêtre, on va s’intéresser aux boutons. Leur mise en place est très similaire à celle des Labels. Cependant, on peut leur ajouter d’autres arguments
command
qui spécifiera la fonction à éxécuter en cas de clic sur le boutonwidth
etheight
qui permettent de modifier respectivement sa largeur et sa longueur. Si ils ne sont pas spécifiés, la taille du bouton sera celle nécessaire pour que son texte s’affiche
nb_clicks=0 def compteur(): global nb_clicks nb_clicks += 1 print(nb_clicks) bouton1 = Button(fenetre, text="Je suis un bouton", font=("Consolas",15), bg="white", fg="black", command=compteur, width=10, height=3)
Ici, on a donc créé un Bouton d’une largeur de 10 et d’un hauteur de 3 qui incrémente un compteur à chaque clic et qui donne la valeur du compteur dans la console
Mais ce que l’on chercherait à faire, ce serait de faire apparaître le texte directement dans la fenêtre.
On créé alors un nouveau Label qui va afficher la valeur de nb_clicks
.
nb_clicks=0 textecompteur = Label(fenetre, text="nombre de clicks : %s" %(nb_clicks), font=("Helvetica",15), bg="#d1fdff", fg="black") #ici, dans la chaîne de caractères, le "%s" sera remplacé par la valeur de la variable placée dans le tuple situé après le % soit nb_clicks def compteur(): global nb_clicks nb_clicks += 1 print(nb_clicks) bouton1 = Button(fenetre, text="Je suis un bouton", font=("Consolas",15), bg="white", fg="black", command=compteur, width=50, height=3)
On se rend alors compte que même si la valeur est incrémentée, le label ne s’actualise pas dans la fenêtre. On va alors ajouter une ligne dans la fonction compteur
qui va mettre à jour ce Label à chaque clic du bouton à l’aide de l’instruction .config()
def compteur(): global nb_clicks nb_clicks += 1 textecompteur.config(text="nombre de clicks : %s" %(nb_clicks))
Voici ce que ça donne:
Cependant, si la fonction à exécuter nécessite des arguments, les choses vont se passer un peu différemment.
Dans cet exemple, on va créer deux boutons, qui vont exécuter la même fonction en cas de clic, mais avec des arguments différents.
Il est nécessaire pour cela d’importer la fonction partial
de la library functools
.
from functools import partial
On créé d’abord notre fonction. Ici, elle prend en argument une couleur et applique cette couleur au Label titre
en cas d’appel de la fonction:
def changer_couleur_titre(couleur): titre.config(fg=couleur)
Ensuite, on créé les boutons avec pour commande partial( nomdelafonction, argument )
bouton2 = Button(fenetre, text="titre rouge", font=("Consolas",15), bg="white", fg="black", command=partial(changer_couleur_titre,"red")) bouton3 = Button(fenetre, text="titre bleu", font=("Consolas",15), bg="white", fg="black", command=partial(changer_couleur_titre,"blue"))
Lorsque l’on va cliquer sur bouton2
le titre va devenir rouge, et sur le bouton3
il deviendra bleu
Ajouter un champ pour entrer du texte
Pour certains programmes, et en particulier les simulateurs, il est nécessaire d’entrer des données manuellement, et c’est là que les Entry entrent en jeu.
Là aussi, le processus est assez similaire aux Labels, la seule différence est que text
est remplacé par textvariable
qui sera donc la variable que l’on va modifier lorsque l’on écrira dans ce champ.
A l’instar des boutons, il est aussi possible de modifier leur taille à l’aide de width
et height
Ici, la création de la variable est un peu différente car il doit s’agir d’une variable tkinter. On procède alors de la manière suivante:
#création de la variable variable = tk.StringVar() variable.set("Vous pouvez me modifier") #création du champ entree = Entry(fenetre, textvariable=variable, font=("Helvetica",15), bg="#d1fdff", fg="black", width=30)
Il faudra utiliser la même méthode à chaque fois que l’on voudra créer des variables pour des chaînes de caractères que l’on voudra afficher dans une interface tkinter
Il est possible aussi possible d’appeler cette variable (en utilisant .get()
car il s’agit d’une variable tkinter) pour modifier du texte par exemple:
def changer_titre(): titre.config(text=variable.get()) bouton4 = Button(fenetre, text="Cliquez pour actualiser", font=("Helvetica",15), bg="#d1fdff", fg="black", command = changer_titre)
Ici, à chaque clic du bouton, le texte du titre sera actualisé pour devenir celui du champ:
Maintenant que l’on sait incorporer différents éléments à notre fenêtre, on va s’intéresser à comment les organiser
Utiliser les boites
Les boites, ou Frames, sont très utiles lorsque l’on utilise tkinter puisqu’elles permettent de regrouper des éléments entre eux et ainsi créer différents menus entre lesquels on peut naviguer.
Il est nécessaire de les définir avant les éléments qui vont en faire partie, c’est pourquoi il est conseillé de les définir juste en dessous de la configuration de la fenêtre.
On créé une boite de la manière suivante, en spécifiant la boite dans laquelle elle est placée, et la couleur de son arrière plan
boitelabels = Frame(fenetre, bg="#d1fdff")
Ici, on a spécifié que la boite apparaîtrait dans la fenêtre principale, mais il est aussi possible de faire apparaître des boites dans des boites.
Comme tout autre élément, si l’on veut qu’une boite apparaisse, il ne faudra pas oublier de l’appeler avec un .pack()
. Si un élément est appelé ainsi mais pas sa boîte, il n’apparaîtra pas, et si jamais il n’est pas appelé et que sa boite si, il n’apparaîtra pas non plus
Pour qu’un élément apparaisse dans une boîte, il suffit de remplacer le fenetre
que l’on utilisait jusqu’à présent par le nom de la boite:
titre = Label(boitelabels, text="Voici un exemple de Label en police consolas et en taille 20", font=("Consolas",20), bg="#d1fdff", fg="black") soustitre = Label(boitelabels, text="Voici un exemple de Label en police Helvetica et en taille 15", font=("Helvetica",15), bg="#d1fdff", fg="black")
Nous allons maintenant essayer de créer un menu nous permettant de naviguer entre tout ce que l’on a créé jusqu’à présent.
On créé alors différentes boites pour nos différents éléments. Dans cet exemple
boitelabels
contiendra les éléments servi à la démonstration de ce que sont les Labelsboitecompteur
contiendra le compteur créé un peu plus tôtboitecouleurs
contiendra les boutons permettant de modifier la couleur du titreboiteentree
contiendra les éléments ayant servi à la démonstration de l’utilité des Entriesboitemenu
contiendra les boutons permettant d’afficher les différentes boites. Elle va être la seule à apparaître lorsque l’on lancera le script et permettra d’afficher les autres
boitecompteur = Frame(fenetre, bg="#d1fdff") boitecouleurs = Frame(fenetre, bg="#d1fdff") boiteentree = Frame(fenetre, bg="#d1fdff") boitemenu = Frame(fenetre, bg="#d1fdff")
En on n’oublie pas de modifier la boite de chaque élément pour qu’il n’apparaisse plus dans la fenêtre principale mais dans la boite dans laquelle on veut qu’il apparaisse
#exemple: ici on place le label textecompteur dans la boitecompteur: textecompteur = Label(boitecompteur, text="nombre de clicks : %s" %(nb_clicks), font=("Helvetica",15), bg="#d1fdff", fg="black")
On va aussi créer des boutons dans boitemenu
qui, lorqu’ils seront cliqués appelleront une autre boite avec un .pack()
et feront disparaître le menu à l’aide de .pack_forget()
. On va aussi mettre en place des boutons de retour au menu dans chacune des autres boites qui vont, eux, faire disparaître leur boite et apparaître le menu en cas de clic;
def afficher_labels(): boitelabels.pack(expand=YES) boitemenu.pack_forget() def afficher_compteur(): boitecompteur.pack(expand=YES) boitemenu.pack_forget() def afficher_couleurs(): boitecouleurs.pack(expand=YES) boitemenu.pack_forget() def afficher_entree(): boiteentree.pack(expand=YES) boitemenu.pack_forget() def retour_menu(): boitemenu.pack(expand=YES) boitelabels.pack_forget() boitecompteur.pack_forget() boitecouleurs.pack_forget() boiteentree.pack_forget() b_labels = Button(boitemenu, text="Afficher les Labels", font=("Consolas",15), bg="white", fg="black", command=afficher_labels, width=75) b_compteur = Button(boitemenu, text="Afficher le compteur", font=("Consolas",15), bg="white", fg="black", command=afficher_compteur, width=75) b_couleurs = Button(boitemenu, text="Afficher les boutons pour changer la couleur du titre", font=("Consolas",15), bg="white", fg="black", command=afficher_couleurs, width=75) b_entree = Button(boitemenu, text="Afficher le champ pour changer le titre", font=("Consolas",15), bg="white", fg="black", command=afficher_entree, width=75) b_retour1 = Button(boitelabels, text="retourner au menu", font=("Consolas",15), bg="white", fg="black", command=retour_menu, width=35) b_retour2 = Button(boitecompteur, text="retourner au menu", font=("Consolas",15), bg="white", fg="black", command=retour_menu, width=35) b_retour3 = Button(boitecouleurs, text="retourner au menu", font=("Consolas",15), bg="white", fg="black", command=retour_menu, width=35) b_retour4 = Button(boiteentree, text="retourner au menu", font=("Consolas",15), bg="white", fg="black", command=retour_menu, width=35)
Tout ça est bien beau, mais pour l’instant on ne sait qu’afficher différents éléments les uns au dessous des autres, mais pas les uns à côté des autres. C’est là que les grilles vont intervenir
Utiliser les grilles
Pour faire une grille, on va remplacer les .pack()
que l’on utilisait par des .grid()
. Il faut savoir que si l’on utilise une grille pour un élément, tous les éléments présents dans la même boite devront eux aussi utiliser cette même grille.
Comme on voudrait seulement placer deux des boutons côte à côte, on va les placer dans une sous boite de la boite du menu:
#création de la sous boite sousboitemenu = Frame(boitemenu, bg="#d1fdff")
Et on modifie la boite des deux boutons concernés, ainsi que leurs dimensions pour qu’ils soient alignés avec les autres. (On ajoute aussi un \n
dans le texte du second bouton pour qu’il s’affiche sur deux lignes)
b_compteur = Button(sousboitemenu, text="Afficher le compteur", font=("Consolas",15), bg="white", fg="black", command=afficher_compteur, width=36, height=2) b_couleurs = Button(sousboitemenu, text="Afficher les boutons \npour changer la couleur du titre", font=("Consolas",15), bg="white", fg="black", command=afficher_couleurs, width=36, height=2)
Il est temps maintenant de placer les boutons en grille à l’aide de .grid()
.
Cette méthode accepte plusieurs arguments:
row
qui définit la ligne dans laquelle l’élément va être placécolumn
qui définit sa colonnesticky
qui définit de quel côté de la fenêtre l’élément doit se rapprocher ( W, E, S ou N pour les quatre points cardinaux)padx
etpady
(optionnels) qui définissent les marges en x et en y
b_compteur.grid(row=1, column=0, sticky=W, pady=5, padx=5) b_couleurs.grid(row=1, column=1, sticky=W, pady=5, padx=5)
On obtient alors le résultat suivant:
Conclusion
Voilà, vous possédez maintenant les bases nécessaires pour pouvoir créer vos propres interfaces graphiques pour vos scripts Python !
Si jamais certains éléments ne sont pas assez clairs, vous pouvez toujours télécharger le script créé pour ce tutoriel afin de le tester ou de lire son code.
Etudiant au lycée Pasteur de 2020 à 2023 (en toute logique)
Python 3è langue