Interface graphique en Python

Tkinter



Bibliothèque tkinter et interface graphique / GUI

Dans cette partie, on va développer et programmer une interface graphique qui va permettre d'interagir avec un programme.
On parle de graphical user interface ou GUI pour désigner une telle interface. Chaque composant d'une telle interface, bouton, texte, image, menu déroulant, , … , s'appelle un widget, pour window (fenêtre) gadget.

Tkinter (pour Tool kit interface) est la bibliothèque graphique libre d'origine pour le langage Python, permettant la création d'interfaces graphiques. Comme toute bibliothèque python, on importe tkinter avec
from tkinter import *
La programmation d'une GUI change la manière d'aborder la programmation. Il s'agit alors de la programmation dite "événementielle".
Jusqu'ici, les programmes s'exécutaient "linéairement", c'est-à-dire de la 1ère ligne à la dernière, dans l'ordre, sans retour en arrière, sauf à l'intérieur de boucles et l'appel de fonctions.
Dans une GUI, l'exécution répond aux actions de l'utilisateur, en fonction de ses interactions avec les différents widgets.

Premiers exemples

Affichage simple: hello world

from tkinter import *
gui=Tk()

texte=Label(gui,text="coucou !",background="yellow",width=10,height=4)
texte.pack()

gui.mainloop()
Pour obtenir, à l'exécution, une nouvelle fenêtre qui s'ouvre:

Exemple 2: texte et un bouton

from tkinter import *
gui=Tk()

texte=Label(gui,text="coucou !",background="yellow",width=10,height=3)
texte.pack()

def change_text():
    texte["text"]="Ciao"

bouton=Button(gui, text="Change", command=change_text)
bouton.pack()

gui.mainloop()
pour obtenir

Exemple avec champ de texte et boutons

On reprend l'exemple sur les tables de multiplication, en ajoutant une interface.
from tkinter import *
from random import randint

gui=Tk()

Question=Label(gui,text="Nouveau calcul ?",background="yellow")
Question.pack()

def calcul():
    global a,b
    a=randint(0,10)
    b=randint(0,10)
    Question["background"]="yellow"
    Question["text"]=str(a)+"x"+str(b)

def valid():
    global a,b
    quest=Question["text"]
    rep=reponse.get()
    if int(rep)==a*b:
        Question["background"]="green"
        Question["text"]=quest+"="+rep+"\nBravo !"
    else:
        Question["text"]=quest+"="+rep+"\nBof !"
        Question["background"]="red"

reponse=StringVar()
entree = Entry(gui,textvariable=reponse, width=4)
entree.pack()
    
bouton_valid=Button(gui, text="Valider", command=valid)
bouton_valid.pack()

bouton_calcul=Button(gui, text="Nouveau calcul", command=calcul)
bouton_calcul.pack()

bouton_close=Button(gui, text="Fermer", command=gui.quit)
bouton_close.pack(pady=6)

gui.mainloop()
pour obtenir l'interface avec une zone de texte et 3 boutons:

Principaux widgets

Label - zone de texte

Une zone de texte se définit avec la commande Label, par exemple,
from tkinter import *
gui=Tk()

lbl=Label(gui,text="toto")
lbl.pack()
gui.mainloop()
On peut accéder et modifier le texte par
from tkinter import *
gui=Tk()

lbl=Label(gui,text="toto")
lbl.pack()
print(lbl['text'])

# on change le texte: 
lbl['text']="tata"

gui.mainloop()

Boutons

Un bouton se définit avec la commande Button, par exemple,
from tkinter import *
gui=Tk()

btn=Button(gui,text="Click me !")
btn.pack()
gui.mainloop()
La moindre des choses est de relier un bouton à une action qui sera effectuée lorsqu'on le presse effectivement. Cette action se définit via une fonction dans laquelle on décrit les actions souhaitées. On lie le bouton et cette fonction via le paramètre command du bouton:
from tkinter import *
gui=Tk()

def MaFonction():
    print("Oh oh, le bouton a été cliqué !")

btn=Button(gui,text="Click me !",command=MaFonction)
btn.pack()
gui.mainloop()

Exercice 1: Reprendre la fenêtre précédente avec la zone de texte "toto" et y ajouter un bouton qui change le texte lorsqu'on le presse.

Zone de saisie

Un champ de saisie de texte est l'analogue graphique de la commande input. Il permet de fournir une zone de texte dans laquelle l'utilisateur va pouvoir écrire.
Le champ se déclare grâce à la commande Entry:
from tkinter import *
gui=Tk()
champ=Entry(gui,text=texte_saisi)
champ.pack()
Une particularité est que le texte, ici dans la variable texte_saisi, est justement variable. On le définit alors comme un objet particulier de type StringVar. On récupère ensuite sa valeur avec la méthode get, par exemple
from tkinter import *
gui=Tk()

texte_saisi=StringVar()
champ=Entry(gui,text=texte_saisi)
champ.pack()

def verif():
    print(texte_saisi.get())

btn=Button(gui,text='click me',command=verif)
btn.pack()

gui.mainloop()
Exercice 2: Modifier le programme précédent pour que la zone de saisie devienne verte si le mot saisi est "python", et rouge sinon.

Remarque: Pour faire une boîte de dialogue type "mot de passe", on peut ajouter l'option show="*" dans la commande Entry.

Exercice 3: Créer une fenêtre avec deux zones de saisie et un bouton.
Lorsqu'on appuie sur le bouton, le résultat de la multiplication des deux nombres entrés dans chaque zone de saisie s'affiche.

Canvas: zone de dessin

Voir la partie suivante sur le widget canvas



key binding: interaction avec le clavier et/ou la souris

Création d'une nouvelle fenêtre



Top Programmation en python



Quelques liens vers d'autres ressources: