tkinter
est un module de «gadgets
graphiques» (widgets - contraction de windows et
gadget) intégré par défaut dans
Python. On utilisera cette
bibliothèque graphique en raison de sa simplicité. Il existe
aussi d'autres bibliothèques de ce type
(wxPython
, pyQT
,
pygame
...) mais elles ne seront pas
abordées au cours de cette formation.
Un manuel de référence sur tkinter
(168
pages en anglais !) est disponible en
cliquant
sur ce lien.
Le principe général est :
- de créer une fenêtre graphique (cf. ci-contre) ;
- puis de placer et organiser des éléments (boutons,
textes, zones de dessin, etc...) à l'intérieur de cette
fenêtre.
Important - Avant de commencer
Même si la formation d'aujourd'hui va vous apprendre le B.A.-BA pour programmer
une interface graphique, il ne faut surtout pas oublier...
qu'une interface graphique n'est qu'une surcouche d'un programme déjà
fonctionnel !
De manière générale, on commence par concevoir un code fonctionnel en mode
console puis on ajoute fenêtre, boutons, canevas et interaction afin de
rendre ce programme plus convivial dans son utilisation.
Organiser une fenêtre
Une fenêtre est tout simplement un rectangle affiché à
l'écran dans lequel on place d'autres objets graphiques
(widgets) après les avoir
affectés à des variables.
tkinter
permet de manipuler de très
nombreux objets graphiques (comme l'atteste
le document de référence). Pour éviter de se perdre
entre tous ces widgets, on se limitera dans cette formation
à :
Widget |
Description |
Label() |
Zone d'affichage de texte. |
Entry() |
«Formulaire» qui permet de récupérer du
texte saisi par l'utilisateur. |
Button() |
Un bouton sur lequel cliquer. |
Canvas() |
Canevas très «souple» qui correspond à
une zone de dessin ou d'animation. C'est souvent le
widget le plus utilisé. |
Une fois les widgets créés, il faut anticiper leur
positionnement dans la fenêtre grâce à la méthode
.grid()
appliquée au widget :
widget_nom.grid(row=..., column=...)
La fenêtre est alors «partagée» virtuellement en
lignes (row
) et colonnes
(column
) numérotées à partir de
0
(valeurs par défaut). On obtient
ainsi des «cellules» (comme la feuille de
calcul d'un tableur) dans lesquelles seront placées
les différents widgets.
Outre les numéros de ligne (row = a
)
et de colonne (column = b
) indiquant
la «cellule» dans laquelle placer le widget, la
méthode .grid()
accepte des paramètres
optionnels :
rowspan = n
fusionne n
cellules
verticalement depuis la cellule dans laquelle le widget
est positionné.
columnspan = n
fusionne n
cellules
horizontalement depuis la cellule dans laquelle le
widget est positionné.
padx
et pady
: écart
(en pixels) entre le widget et le bord de sa
«cellule» (horizontal puis vertical).
-
sticky = position
permet de positionner le widget
dans la cellule si celle-ci est trop grande pour lui.
position
peut prendre pour valeurs
N
, SW
, E+W
,
etc...
La disposition des différents widgets dans une fenêtre peut
modifier sensiblement le comportement d'un programme.
Anticiper l'apparence désirée à l'aide d'un papier
et d'un crayon se révèle vite indispensable..
Exemple d'analyse de fenêtre
En observant l'organisation de la fenêtre, placez dans le
tableau ci-dessous les types des différents widgets en
cohérence avec leur position.
Fenêtre principale
On commence par définir une une fenêtre « vide », de
dimensions modifiables à loisir. Les trois boutons en haut à
droite de la fenêtre sont actifs :
##----- Importation des Modules -----##
from tkinter import *
##----- Création de la fenêtre -----##
fen = Tk() # Objet stockée dans la variable "fen"
##-----Programme principal-----##
fen.mainloop() # Boucle d'attente des événements
La fenêtre stockée dans la variable fen
est un
objet informatique. Pour modifier
(manipuler) cet objet, il faut
lui appliquer une méthode selon la syntaxe :
objet.methode(parametres_eventuels)
Méthodes qu'on peut appliquer à une fenêtre
Méthode(paramètre) |
Description |
fen.title('titre') |
'titre' de la
fenêtre sous forme de chaîne de caractères
(string ) |
fen.geometry('AxB+C+D') |
Fenêtre de A pixels de large et
B pixels de haut. Le coin supérieur
gauche de la fenêtre est situé à C
pixels en abscisses et D pixels en
ordonnées du coin supérieur gauche de l'écran. |
fen.mainloop() |
Obligatoire pour que la fenêtre
reste ouverte ! |
Définir un bouton
L'instruction :
bouton_nom = Button(parent, text='…', command=fonction)
affecte un widget Button()
à la
variable intitulée bouton_nom
. De plus,
- Ce bouton se place dans le widget contenu dans la variable
parent
(généralement une fenêtre).
- Le texte
'…'
sera
affiché sur le bouton et le clic lancera la fonction
fonction
.
Attention !
La fonction appelée doit être définie
avant la création du bouton. De plus, cette
fonction ne doit pas comporter d'argument, ce qui
nécessite de faire preuve d'ingéniosité (ou
d'utiliser la fonction lambda
qui sera utilisée
dans un des exercices).
Méthodes qu'on peut appliquer à un bouton stocké dans btn
Méthode(paramètre) |
Description |
btn.grid(row=…, column=…) |
Voir le paragraphe
Organiser une fenêtre |
btn.configure(para=…) |
Modifie le(s) paramètre(s) indiqué(s).
Avec text='…' ,
le texte affiché change. |
btn.destroy() |
Suppression du bouton. |
Exemple : Cas particulier du bouton [Quitter]
On complète la fenêtre créée dans le paragraphe précédente
avec un bouton de fermeture :
##----- Importation des Modules -----##
from tkinter import *
##----- Création de la fenêtre -----##
fen = Tk() # Stockée dans la variable "fen"
fen.title('Ma première fenêtre') # Titre de la fenêtre
##----- Création des boutons -----##
bouton_quitter = Button(fen, text='Quitter')
##-----Programme principal-----##
fen.mainloop() # Boucle d'attente des événements
- Copiez ce code dans un environnement en
Python puis
exécutez-le. Que se passe-t-il ?
- Complétez la ligne
10
pour que le
bouton [Quitter] s'affiche correctement dans la
fenêtre créée.
- Une fois le bouton apparu, cliquez dessus.
Que se passe-t-il ?
- Il faut associer une fonction à la commande que doit
exécuter le
bouton_quitter
. La méthode
qui permet de fermer une fenêtre (stockée dans
la variable fen
) est
fen.destroy()
.
- Question 1°/
- Question 2°/
- Question 3°/
- Question 4°/
Le bouton [Quitter] ne s'affiche pas dans
la fenêtre.
Un exemple de code :
##----- Importation des Modules -----##
from tkinter import *
##----- Création de la fenêtre -----##
fen = Tk() # Stockée dans la variable "fen"
fen.title('Ma première fenêtre') # Titre de la fenêtre
##----- Création des boutons -----##
bouton_quitter = Button(fen, text='Quitter')
bouton_quitter.grid(row=0, column=0)
##-----Programme principal-----##
fen.mainloop() # Boucle d'attente des événements
Il n'y a pas de commande associée au bouton donc un
clic sur celui-ci ne déclenche rien...
Attention, pas de parenthèses pour faire
appel à une fonction par l'intermédiaire
d'un bouton...
##----- Importation des Modules -----##
from tkinter import *
##----- Création de la fenêtre -----##
fen = Tk() # Stockée dans la variable "fen"
fen.title('Ma première fenêtre') # Titre de la fenêtre
##----- Création des boutons -----##
bouton_quitter = Button(fen, text='Quitter', command=fen.destroy)
bouton_quitter.grid(row=0, column=0)
##-----Programme principal-----##
fen.mainloop() # Boucle d'attente des événements
Définir un zone de texte
L'instruction :
zone_nom = Label(parent, text='BlaBla')
affecte un widget Label()
à la
variable intitulée zone_nom
. De plus,
- Cette zone de texte se place dans le widget contenu
dans la variable
parent
(généralement une fenêtre).
- Elle peut contenir aussi bien du texte
(sic !) que des images (voir le
chapitre sur les
Canvas pour la méthode).
Méthodes qu'on peut appliquer à une zone de texte stockée dans txt
Méthode(paramètre) |
Description |
txt.grid(row=…, column=…) |
Voir le paragraphe
Organiser une fenêtre |
txt.configure(para=…) |
Modifie le(s) paramètre(s) indiqué(s).
Avec text='…' ,
le texte affiché change. |
txt.destroy() |
Suppression de la zone de texte. |
Suite de l'exemple
Complétez le programme ci-dessous pour qu'il affiche une
fenêtre avec une zone de texte ayant l'apparence ci-contre :
##----- Importation des Modules -----##
from tkinter import *
##----- Création de la fenêtre -----##
fen = Tk() # Stockée dans la variable "fen"
fen.title('Ma première fenêtre') # Titre de la fenêtre
##----- Création des boutons -----##
bouton_quitter = Button(fen, text='Quitter', command=fen.destroy)
bouton_quitter.grid(row = 0, column = 0)
##----- Création des zones de texte -----##
texte_aide = # A compléter...
##-----Programme principal-----##
fen.mainloop() # Boucle d'attente des événements
Il ne faut pas oublier de modifier les paramètres
de la méthode .grid()
appliquée au
bouton_quitter
.
##----- Importation des Modules -----##
from tkinter import *
##----- Création de la fenêtre -----##
fen = Tk() # Stockée dans la variable "fen"
fen.title('Ma première fenêtre') # Titre de la fenêtre
##----- Création des boutons -----##
bouton_quitter = Button(fen, text='Quitter', command=fen.destroy)
bouton_quitter.grid(row = 1, column = 0, sticky=E)
##----- Création des zones de texte -----##
texte_aide = Label(fen, text='Appuyer sur le bouron pour fermer la fenêtre')
texte_aide.grid(row = 0, column = 0)
##-----Programme principal-----##
fen.mainloop() # Boucle d'attente des événements
Définir un formulaire
L'instruction :
saisie_nom = Entry(parent, textvariable=StringVar())
affecte un widget Entry()
à la
variable intitulée saisie_nom
. De plus,
- Ce formulaire se place dans le widget contenu
dans la variable
parent
(généralement une fenêtre).
- On peut récupérer le texte entré par l'utilisateur
avec la méthode
.get()
.
Méthodes qu'on peut appliquer à un formulaire stocké dans form
Méthode(paramètre) |
Description |
forme.grid(row=…, column=…) |
Voir le paragraphe
Organiser une fenêtre |
form.get() |
Permet de récupérer le texte entré par l'utilisateur.
Attention de bien affecter ce texte à une
variable... |
form.configure(para=…) |
Modifie le(s) paramètre(s) indiqué(s). |
form.destroy() |
Suppression du formulaire. |
Fin de l'exemple : fenêtre « interactive »
Le but de cet exemple est de concevoir la
fenêtre ci-contre. L'utilisateur est invité à
entrer son prénom. Une fois le bouton
[Valider] enclenché, s'affiche le message
« Bonjour … » où les pointillés … sont
remplacés par le prénom saisi.
Compléter la définition de la fonction prenom()
ainsi
que les paramètres des différentes méthodes .grid()
afin
que le programme devienne fonctionnel.
##----- Importation des Modules -----##
from tkinter import *
##----- Définitions des Fonctions -----##
def prenom():
""" Entrées : Fonction déclenchée par le bouton - pas d'entrée
Sorties : Insère le prénom de l'utilisateur dans une zone de texte"""
# A compléter
##----- Création de la fenêtre -----##
fen = Tk()
fen.title('Fenêtre interactive')
##----- Création des boutons -----##
bouton_valider = Button(fen, text='Valider', command=prenom)
bouton_valider.grid(row = …, column = …, padx = …, pady = …)
bouton_quitter = Button(fen, text='Quitter', command=fen.destroy)
bouton_quitter.grid(row = …, column = …, padx = …, pady = …)
##---- Création des zones de texte -----##
texte_question = Label(fen, text='Entrez votre prénom puis validez :')
texte_question.grid(row = …, column = …, padx = …, pady = …)
texte_reponse = Label(fen, text='')
texte_reponse.grid(row = …, column = …, …………………………, padx = …, pady = …)
##----- Création des formulaires -----##
form_texte = Entry(fen, textvariable=StringVar())
form_texte.grid(row = …, column = …, padx = …, pady = …)
##----- Programme principal -----##
fen.mainloop()
##----- Importation des Modules -----##
from tkinter import *
##----- Définitions des Fonctions -----##
def prenom():
""" Entrées : Fonction déclenchée par le bouton - pas d'entrée
Sorties : Insère le prénom de l'utilisateur dans une zone de texte"""
a = form_texte.get() # Un formulaire est un objet - variable globale
texte_reponse.configure(text='Bonjour ' + a)
##----- Création de la fenêtre -----##
fen = Tk()
fen.title('Fenêtre interactive')
##-----Création des boutons-----##
bouton_valider = Button(fen, text='Valider', command=prenom)
bouton_valider.grid(row = 2, column = 0, padx = 3, pady = 3)
bouton_quitter = Button(fen, text='Quitter', command=fen.destroy)
bouton_quitter.grid(row = 2, column = 1, padx = 3, pady = 3)
##-----Création des zones de texte-----##
texte_question = Label(fen, text='Entrez votre prénom puis valider :')
texte_question.grid(row = 0, column = 0, padx = 3, pady = 3)
texte_reponse = Label(fen, text='')
texte_reponse.grid(row = 1, column = 0, columnspan = 2, padx = 3, pady = 3)
##-----Création des formulaires-----##
form_texte = Entry(fen, textvariable=StringVar())
form_texte.grid(row = 0, column = 1, padx = 3, pady = 3)
##-----Programme principal-----##
fen.mainloop()
Méthodes applicables à n'importe quel widget
Les méthodes ci-dessous s'appliquent à n'importe quel
widget. Elles permettent de récupérer des informations
sur ces widgets dans l'éventualité où certains paramètres
ont été modifiés au cours du programme.
- Récupérer sous forme d'entier la hauteur actuelle
(en
px
) d'un widget :
h = widget_nom.winfo_reqheight()
- Récupérer sous forme d'entier la largeur actuelle
(en
px
) d'un widget :
h = widget_nom.winfo_reqwidth()
- Supprimer un widget (et tous ses widgets
enfants) :