Un bouton à cliquer

tkinter est un module GUI (graphical user interface). Il est moins complet que d'autres modules python (tel que pygame par exemple) mais est, de ce fait, plus simple de prise en main.

Les quelques pages consacrées ici à ce module ont pour objectif d'en faciliter sa découverte. Vous devrez compléter par vous-même son apprentissage (à l'aide des nombreux exemples que l'on trouve sur le web) en fonction des besoins de votre projet final.

Après avoir lu les pages de cours et traité les exercices proposés ici, vous pourrez compléter par la consultation des documents ciblés ici.

On pourra aussi consulter une doc 'brute' : tkinter, tkinter.ttk.

Pour finir, remarquons que, plus encore que pour l'utilisation des objets de type classique (liste, chaîne, tuple...), il peut être éclairant de lire une initiation à la programmation orientée objet afin de mieux saisir la syntaxe utilisée en permanence dans l'utilisation d'une interface graphique.

Un bouton à cliquer

Pour présenter tkinter, nous commençons par un court exemple (qui dans un premier temps n'aura aucun effet) : placer un bouton à cliquer dans une fenêtre graphique. Cet exemple prendra tout son intérêt quand nous verrons un peu plus loin comment faire en sorte qu'un clic sur ce bouton commande l'exécution d'une fonction.


# import du module tkinter :
import tkinter 
# ouverture d'un objet fenetre de classe Tk, 
# ce qui correspond à une fenêtre graphique :
fenetre = tkinter.Tk()  
# définition d'un bouton lié à fenetre
# le bouton affichera le texte "Je suis à cliquer " :
bouton = tkinter.Button(fenetre, text = "Je suis à cliquer ") 
# instruction pour l'affichage du bouton dans fenetre :
bouton.pack() 
# pour maintenir la fenêtre fenetre ouverte 
# (boucle qui lance une "surveillance" des événements) :
fenetre.mainloop()

Testez ce code. Vous pouvez cliquer sur le bouton (mais cela n'a pour le moment aucun effet).
bouton à cliquer

Vous remarquerez que la fenêtre s'ouvre par défaut :

  • en s'ajustant à son contenu (ici le seul bouton)
  • en général en haut à gauche de l'écran
  • avec le titre tk dans la bordure haute

On peut modifier ces comportements à l'aide de la méthode geometry. fenetre.geometry("300x200+150+100") a pour effet d'ouvrir une fenêtre de taille 300 sur 200 pixels et décalée sur l'écran en x de 150 px et en y de 100 px.

Le titre est quant à lui modifié avec la méthode title.


import tkinter
fenetre = tkinter.Tk()  
fenetre.geometry("300x200+150+100")
fenetre.title('Un titre adapté')
bouton = tkinter.Button(fenetre, text = "Je suis à cliquer ") 
bouton.pack() 
fenetre.mainloop()

fenêtre avec titre

On voit dans cette situation que la méthode pack() place les objets (widgets) a priori en haut de la fenêtre parent. Ce comportement se modifie à l'aide de l'attribut side (qui peut prendre les valeurs 'top', 'bottom', 'left', 'right').


import tkinter
fenetre = tkinter.Tk()  
fenetre.geometry("300x200+150+100")
fenetre.title('Un titre adapté')
bouton = tkinter.Button(fenetre, text = "Je suis à cliquer ") 
bouton.pack(side='bottom') 
fenetre.mainloop()

bouton en bas

Dans ce dernier placement, on pourrait ne pas apprécier que le bouton soit collé au bas de la fenêtre. On règle ce détail avec l'attribut pady qui va mettre un peu de marge autour du widget suivant la direction de l'axe (Oy).


import tkinter
fenetre = tkinter.Tk()  
fenetre.geometry("300x200+150+100")
fenetre.title('Un titre adapté')
bouton = tkinter.Button(fenetre, text = "Je suis à cliquer ") 
bouton.pack(side='bottom',pady=20) 
fenetre.mainloop()

bouton en bas

Un bouton qui commande.

Nous voyons dans ce second paragraphe comment faire en sorte qu'un clic sur le bouton commande l'exécution d'une fonction.

Nous définissons ici une simple fonction qui provoquera un affichage dans le terminal d'exécution. L'exécution de cette commande par clic est obtenue en ajoutant command = nomDeLaFonction dans l'instruction de définition du bouton (attention, pas de () ici après le nom de la fonction).


# import du module tkinter :
import tkinter 


def coucou():
    print("Coucou, je suis un effet du clic.")


# ouverture d'un objet fenetre de classe Tk : 
fenetre = tkinter.Tk()  
# définition d'un bouton lié à fenetre
# le bouton affichera le texte "Cliquez-moi"
# et permettra de commander l'exécution de la fonction coucou :
bouton = tkinter.Button(fenetre, text = "Cliquez-moi", command = coucou) 
# instruction pour l'affichage du bouton dans fenetre :
bouton.pack() 
# lancement du réceptionnaire d'événements :
fenetre.mainloop()

Testez ce code. Vous pouvez cliquer plusieurs fois sur le bouton : la fonction s'exécute à chaque clic.

Par la suite, nous verrons également comment afficher du texte dans la fenêtre graphique elle-même.

Commande avec paramètres.

Nous voulons maintenant avoir un message en paramètre de la fonction coucou.

Testez le code ci-dessous et observez ce qu'il se passe.


# import du module tkinter :
import tkinter 


def coucou(message):
    print(message)


# ouverture d'un objet fenetre de classe Tk : 
fenetre = tkinter.Tk()  
# définition d'un bouton lié à fenetre
# le bouton affichera le texte "Cliquez-moi"
# et permettra de commander l'exécution de la fonction coucou :
bouton = tkinter.Button(fenetre, text = "Cliquez-moi", command = coucou("Bonjour")) 
# instruction pour l'affichage du bouton dans fenetre :
bouton.pack() 
# lancement du réceptionnaire d'événements :
fenetre.mainloop()

Vous constatez que le message "Bonjour" passé en paramètre est affiché à l'ouverture de la fenêtre. Ensuite, on constate que le bouton n'a aucun effet.

Cela est du au fait que command devait prendre pour valeur la fonction à exécuter et non le résultat de l'exécution de la fonction (avec une valeur explicite de paramètre). C'est la raison pour laquelle nous n'avions pas mis plus haut de parenthèses après le nom de la fonction dans le code command= coucou.

Mais alors comment faire si l'on veut passer des paramètres ? Il faut se tourner vers les fonctions lambda (vous rechercherez sur le web pour en savoir plus sur les fonctions lambda, ici seul l'usage dans ce contexte nous intéresse).

Testez :


# import du module tkinter :
import tkinter 


def coucou(message):
    print(message)


# ouverture d'un objet fenetre de classe Tk : 
fenetre = tkinter.Tk()  
# définition d'un bouton lié à fenetre
# le bouton affichera le texte "Cliquez-moi"
# et permettra de commander l'exécution de la fonction coucou :
bouton = tkinter.Button(fenetre, text = "Cliquez-moi",command =  lambda :  coucou("Bonjour")) 
# instruction pour l'affichage du bouton dans fenetre :
bouton.pack() 
# lancement du réceptionnaire d'événements :
fenetre.mainloop()

Un bouton qui disparaît.

Donnons un autre exemple simple d'action sur les boutons.

Dans l'exemple ci-dessous, un clic sur le bouton 1 le fait disparaître. Un clic sur le bouton 2 le fait réapparaître.

Essayez !


from tkinter import *

def cachecache(bouton):
    bouton.grid_forget() # le widget de nom bouton est "oublié"
    
def coucou(bouton,ligne, colonne) :
    # le widget de nom bouton est placé dans une grille en (ligne, colonne) :
    bouton.grid(row=ligne, column=colonne) 



fenetre = Tk()

btn=Button(fenetre, text="bouton 1", command = lambda : cachecache(btn))
btn.grid(row=0,column=0) # placement de btn en (ligne 0, colonne 0)

btn2 = Button(fenetre, text='bouton 2', command = lambda : coucou(btn,0,0) )
btn2.grid(row=1,column=0) # placement de btn2 en (ligne 1, colonne 0)

fenetre.mainloop()

Avec une petite variante que vous chercherez à comprendre en vous aidant de pages web :


from tkinter import *

def cachecache(event):
    event.widget.grid_forget()
    
def coucou(bouton,ligne, colonne) :
    bouton.grid(row=ligne, column=colonne)

fenetre = Tk()

btn=Button(fenetre, text="bouton 1")
btn.bind('<Button-1>', cachecache)
btn.grid(row=0,column=0)

btn2 = Button(fenetre, text='bouton 2', command = lambda : coucou(btn,0,0) )
btn2.grid(row=1,column=0)

fenetre.mainloop()

Vous pouvez maintenant traiter les premiers exercices.