Chapitre 10 : TP4. Les Widgets et leur positionnement.
..... a. Widget Entry.
..... b. Widget RadioButton.
..... c. Positionnement des widgets : the grider.
a) Widget Entry.
Nous aurons parfois besoin de récupérer des saisies de l'utilisateur. En mode console, ceci faisait simplement à l'aide de la fonction input.
En mode graphique, nous placerons dans la fenêtre un widget "
Entry" (champ d'entrée), dont le contenu pourra être récupéré à l'aide la
méthode "get".
Ainsi, dans le programme suivant nous avons lié l'événement "appui sur la touche Return" au widget champ d'entrée. La fonction affich mettant alors à jour l'affichage :
Copions et testons le programme :
##### Importation #####
from tkinter import *
##### Fonction #####
def affich(event) :
prenom = champ.get() # La méthode get permet de récupérer
# le contenu saisi dans un widget Entry.
lab2.configure(text="Bonjour " + prenom + " !")
##### Main #####
fen = Tk()
lab1 = Label(fen, text ='Entrez votre prenom et terminez par Entrée :')
lab1.pack()
champ = Entry(fen)
champ.pack()
lab2 = Label(fen, text ='')
lab2.pack()
champ.bind('', affich)
fen.mainloop()
Exercice 1 :
Pour vos nouveau site web, vous auriez besoin d'une petite application demandant à l'utilisateur son âge et lui répondant selon l'âge saisi : "Vous êtes mineur." ou "Vous êtes majeur." :
Indication :
les contenus de champ récupérés par la méthode get sont de type string.
b) Widget RadioButton.
Cette partie ne sera utile à étudier que pour ceux qui choisiront le projet : "logiciel de dessin".
Dans un logiciel, ou dans un formulaire de site internet, on a souvent besoin de cases à cocher, permettant à l'utilisateur choisir un, et un seul choix (ou mode) parmi plusieurs :
Ce widget est un peu plus technique à mettre en oeuvre que ceux vus jusqu'à présent. Nous allons tenter de le décomposer :
b)1) Création des cases à cocher.
- Comme on le devine, c'est un widget "composite" composé en réalité plusieurs widgets (chaque case à cocher), mais reliés entre eux (une seule case peut être cochée à la fois).
- Chaque bouton radio représente un choix possible et se compose de deux parties : l’indicateur et l’étiquette (case à cocher et texte).
- Enfin ces boutons devront être reliés entre eux par une variable de contrôle de tKinter qui sera de type entier ou texte : IntVar ou StringVar.
La valeur de cette variable correspondra à la case sélectionnée.
C'est cette variable qui va permettre de récupérer le choix de l'utilisateur, mais aussi aux boutons de communiquer entre eux : lorsque l'utilisateur clique une case, les autres se décochent.
Voyons ce que cela donne :
################## Importations ##################
from tkinter import *
################## Main ##################
fen = Tk()
# Création des étiquettes des boutons :
etiquette = ['Poulet fraises', 'Merguez chocolat', 'Boeuf chantilly', 'En fait, je vais aller voir ailleurs']
# Création de la variable de contrôle et définition de ses valeurs :
controle = IntVar()
valeur = [0,1,2,3]
# Création des 4 boutons radios :
for i in range(4) :
bouton = Radiobutton(fen, text = etiquette[i], variable = controle, value = valeur[i], font = 'Arial 16 bold', fg = 'DeepPink4')
bouton.pack()
fen.mainloop()
Remarques :
- Remarquons la correspondance entre les listes "etiquette" et "valeur" :
- lorsqu'on coche "Poulet fraises", la variable de contrôle vaut 0,
- lorsqu'on coche "Merguez chocolat", la variable de contrôle vaut 1,
- etc ...
- Pour obtenir le même rendu visuel que ci-dessus, il aurait fallu ajouter : font = 'Arial 16 bold' et fg = 'DeepPink4'
dans les arguments de la fonction RadioButton.
b)2) Des cases à cocher en forme de boutons poussoirs.
Dans les lgiciels courants(LibreOffice, Geogebra ...), les cases à cocher sont souvent représentées sous forme de boutons poussoirs (regroupés dans un bandeau horizontal en haut de la fenêtre).
tKinter nous offre cette possibilités : il suffit d'ajouter l'option : indicatoron = 0 dans les paramètres des RadioButton (comprendre : indicator on !).
################## Importations ##################
from tkinter import *
################## Main ##################
fen = Tk()
fen.configure(bg = 'ivory')
controle=IntVar()
etiquette = ['Poulet fraises', 'Merguez chocolat', 'Boeuf chantilly', 'En fait, je vais aller voir ailleurs']
val=[0,1,2,3]
for i in range(4) :
bouton = Radiobutton(fen, text=etiquette[i], variable=controle, value=val[i], indicatoron = 0, font='Arial 16 bold', fg='Red4', bg = 'light grey')
bouton.pack()
fen.mainloop()
b)3) Des icones plutôt que du texte !
Dans les logiciels courants, on remaque aussi que, plutôt qu'un texte, on opte pour une icône sur le bouton : plus rapide à trouver pour l'utilisateur !
tKinter ne manque pas non plus de nous offrir cette possibilité, qui celle que nous retiendrons dans les projets de création de logiciels de dessin :
- au lieu d'une liste de textes dans étiquette, nous opterons pour une liste d'images que nous appellerons img
(les fichiers images sont à placer dans le même répertoire que le programme :
   
Souris    
Segment    
Rectangle    
Cercle
),
- au lieu de l'option texte dans les paramètres du RadioButton, nous opterons pour l'option image.
################## Importations ##################
from tkinter import *
################## Main ##################
fen = Tk()
fen.configure(bg = 'ivory')
forme = IntVar()
val = [0, 1, 2, 3]
img = [PhotoImage(file = 'souris.png'), PhotoImage(file = 'rond.gif'), PhotoImage(file = 'carre.gif'), PhotoImage(file = 'segment.gif')]
for i in range(4) :
bouton = Radiobutton(fen, image = img[i], variable = forme, value = val[i], indicatoron=0, bg = 'light grey')
bouton.pack()
fen.mainloop()
Exercice 2 :
Télécharger les fichiers suivants :
   
Bleu    
Jaune    
Rouge    
Vert,
puis composer la fenêtre ci-contre avec 4 boutons radios :
b)4) Récupération des choix de l'utilisateur.
Maintenant que nous savons créer des boutons des boutons radios, il va falloir récupérer les choix de l'utilisateur.
Le contenu des variables de contrôle de tKinter(IntVar ou StringVar) sont accessibles par la méthode
get.
Ainsi, si la variable de contrôle s'appelle
choix, son contenu est obtenu par l'instruction :
choix.get()
Exercice 3 :
On se propose ici composer une fenêtre de choix du menu dans un fast food.
Lorsque l'utilisateur aura sélectionné un menu et cliquera sur "valider",
l'écran affichera son choix et le tarif, comme sur la seconde image.
Télécharger les fichiers suivants :
   
Bleu    
Jaune    
Rouge    
Vert,
puis composer la fenêtre comme ci-dessous avec 4 boutons radios :

   
c) Positionnement des widgets : the grider.
Jusqu'à maintenant, nous avons placé les widgets dans nos fenêtres à l'aide de la méthode
pack. Cette méthode est simple à utiliser, mais peu précise.
Pour des applications ne comportant qu'un canevas, vous pourrez vous contenter de la méthode pack. Pour ceux qui se lanceront dans des projets avec une interface graphique comportant plusieurs boutons ou champs d'entrées,
il sera préférable d'opter pour la méthode
grid.
La méthode grid considère la fenêtre comme un tableau. Il suffit de lui indiquer dans quelle ligne (row) et dans quelle colonne (column) du tableau, on souhaite placer son widget.
Il n'est pas nécessaire d'annoncer à l'avance le nombre de lignes et de colonnes, si bien que l'on peut en rajouter autant que nécessaire, au fil du programme.
On peut numéroter les lignes et les colonnes comme on le souhaite, en partant de zéro, ou de un.
Voici ainsi un programme pour créer dans la fenêtre un formulaire minimaliste :
##### Importation #####
from tkinter import *
##### Main #####
fen = Tk()
lab1 = Label(fen, text ='Nom :')
lab1.grid(row = 0, column = 0)
lab2 = Label(fen, text ='Prenom :')
lab2.grid(row = 1, column = 0)
champ1 = Entry(fen)
champ1.grid(row = 0, column = 1)
champ2 = Entry(fen)
champ2.grid(row = 1, column = 1)
fen.mainloop()
Qui donnerait :
Exercice 4 :
En utilisant des widgets Label et Button, ainsi que la méthode grid, composer la première fenêtre ci-dessous.
Des fonctions gestionnaires seront mises en place, de sorte qu'à chaque fois qu'un bouton sera cliqué, le texte de ce bouton deviendra : "C'est fait !".

   
Un peu mieux encore :
Bien souvent, nos widgets n'auront pas tous la même taille et nous aurons besoin "d'étaler un widget" sur plusieurs lignes ou colonnes.
On peut alors spécifier les arguments "
rowspan" ou "
columnspan" dans la méthode grid (span : envergure, espace, en anglais ).
##### Importation #####
from tkinter import *
##### Fonction ######
def non() :
lab.configure(text = 'Non ! Ceci est un Python !')
##### Main #####
fen = Tk()
can = Canvas(fen, bg = 'ivory')
can.grid(row = 0, column = 0, rowspan = 4)
fichier = PhotoImage(file='serpent.png')
python = can.create_image(0, 0, image = fichier, anchor = 'nw')
bou1 = Button(fen, text = 'Anaconda', bg = 'yellow', command = non, width = 10, font = 'Arial 12 bold')
bou1.grid(row = 0, column = 1)
bou2 = Button(fen, text ='Boa', bg = 'yellow', command = non, width = 10, font = 'Arial 12 bold')
bou2.grid(row = 1, column = 1)
bou3 = Button(fen, text ='Cobra', bg = 'yellow', command = non, width = 10, font = 'Arial 12 bold')
bou3.grid(row = 2, column = 1)
lab = Label(fen, text = '', font = 'Arial 12 bold')
lab.grid(row = 3, column = 1)
fen.mainloop()
Nous obtenons alors :
Pour tester ce programme : télécharger dans le même répertoire que le programme :
Serpent
Exercice 5 :
A l'aide de widgets Canvas et Button, composer la première fenêtre ci-dessous. L'appui sur l'un des boutons commencera par effacer la figure présente dans le canevas et affichera une figure correspondant au bouton cliqué :
