07 Tkinter
Tkinter est un module de base intégré dans Python , normalement vous n'avez rien à faire pour pouvoir l'utiliser. L'un des avantages de Tkinter est sa portabilité sur les OS les plus utilisés par le grand public. Celui-ci permet la création simplement et rapidement d'interface graphique. Toutefois celle-ci doivent être créer à la « main » étant donnée qu'aucun éditeur WYSIWYG n'existe pour cette technologie.
Hello Tkinter
Voici le code source du oh grand classique HelloWorld
from tkinter import *
frame = Tk()
label = Label(frame, text="Hello World")
label.pack()
frame.mainloop()
Widgets
La création d'interface graphique passe par l'ajout au sein de la fenêtre de widgets. Il exite de très nombreux widgets différents au sein de Tkinter, pour la suite de ce tp nous en verrons que quelques uns pour en savoir plus rendez-vous sur cette page et sur l'une des meilleurs documentation (francophone en plus) sur tkinter.
Les boutons
Les boutons permettent de proposer une action à l'utilisateur. Dans l'exemple ci-dessous, on lui propose de fermer la fenêtre.
from tkinter import *
frame = Tk()
exit_button=Button(frame, text="Close me!", command=frame.quit)
exit_button.pack()
frame.mainloop()
Les labels
Les labels sont des espaces prévus pour écrire du texte. Les labels servent souvent à décrire un widget comme un input, nous en avons déjà vu un plus haut dans ce tp.
input
Comme leurs nom l'indique, ils permettent la saisie d'information par l'utilisateur.
from tkinter import *
frame = Tk()
value = StringVar()
value.set("texte par défaut")
entry = Entry(framre, textvariable=value, width=30)
entry.pack()
frame.mainloop()
La valeur de l'input sera stocké dans value
.
Les alertes
Pour pouvoir utiliser les alertes de votre os, vous pouvez importer le module messagebox
from tkinter.messagebox import *
from tkinter import *
frame = Tk()
def callback():
if askyesno('Titre 1', 'Êtes-vous sûr de vouloir faire ça?'):
showwarning('Titre 2', 'Tant pis...')
else:
showinfo('Titre 3', 'Vous avez peur!')
showerror("Titre 4", "Aha")
Button(text='Action', command=callback).pack()
frame.mainloop()
Gestionnaires de positionnement
Comment organiser les widgets dans une fenêtre ?
Bien qu’il y ait différents gestionnaires de positionnement (geometry managers) dans tkinter, nous retiendrons plus spécialement le gestionnaire .grid()
. Ce gestionnaire « découpe » chaque fenêtre ou cadre en une grille formée de lignes et de colonnes.
- Une cellulle (cell) est la zone d’intersection d’une ligne et d’une colonne.
- La largeur de chaque colonne est la largeur de la plus large cellule qu’elle contient.
- La hauteur de chaque ligne est la hauteur de la plus large ligne qu’elle contient.
- Pour les composants graphiques (widgets) qui n’occupent pas toute la surface de leur cellule, on peut indiquer quoi faire de l’espace restant : à l’extérieur du widget, ou en étirant celui-ci pour le combler dans la direction horizontale ou verticale.
- Il est possible de regrouper (spanning) plusieurs cellule en une plus large (ou plus haute).
Lorsqu’on crée un widget, il n’apparaît pas jusqu’à ce qu’il soit positionné au moyen d’un gestionnaire de positionnement. Ainsi, construction et placement du widget se font en deux temps:
truc = Constructeur(parent, ...)
truc.grid(...)
où Constructeur est l’une des classes de widget comme Button, Frame, ... et parent est le widget parent dans lequel le widget enfant est construit. Tous les widgets dispose de la méthode .grid() qui s’utilise pour préciser son emplacement dans une grille.
Voici un exemple d'interface avec l'utilisation d'une grille
from tkinter.messagebox import *
from tkinter import *
def button_validation_callback():
showinfo('Greeting', 'Hello %s' % value.get())
root = Tk()
root.title("Greetings")
value = StringVar()
value.set('Default value')
label = Label(root, text="Hello World")
label.grid(column=0, row=0)
input_r = Entry(root, textvariable=value)
input_r.grid(column=1, row=0)
button_validation = Button(root, text="Say it !", command=button_validation_callback)
button_validation.grid(row=1, column=1)
root.mainloop()
Toutefois notre interface ne se redimensionne pas correctement, pour ce faire nous devons ajouter les lignes de code suivante après la déclaration de notre fenêtre:
root.rowconfigure(0, weight=1)
root.columnconfigure(1, weight=1)
Que se passe t'il si nous rajoutons l'option sticky à notre input:
input_r.grid(column=1, row=0, sticky='nsew')
Une première mise en pratique
Nous venons de découvrir comment créer des interfaces graphiques en python. Mettons en pratique ce nouveau savoir pour créer une application basique qui se chargera de compter la longueur d'un texte pour nous en adoptant bien sûr l'approche TDD.
Il vous est recommandé d'utiliser le composant Text
de Tkinter, voici quelques indications:
textarea = Text(root, wrap='word') # création du composant
textarea.insert(END, "Hello World") # insertion d'un texte
textarea.get("0.0", END) # récupération de l'ensemble du texte
Et si vous souhaitez ajouter une icone à votre application:
from tkinter.ttk import *
root = Tk()
icon = PhotoImage(file='icon.png')
root.title("Counter")
root.iconphoto(False, icon)