Home Python Introduction

Menu principal

Informatique

Mathématiques

Introduction à Python - 11 - Faire une interface graphique avec Tkinter
Informatique - Python
Écrit par Arnaud Kientz   
Index de l'article
Introduction à Python
1 - Généralités
2 - Premiers pas en console
3 - Un premier programme
4 - Structure de contrôle : IF
5 - Structure de contrôle : WHILE
6 - Structure de contrôle : FOR...IN
7 - Synthèse sur les variables
8 - Utilisation des modules
9 - Structure fonctionnelle
10 - Un peu de dessin avec Turtle
11 - Faire une interface graphique avec Tkinter
12 - Quelques exercices de synthèse
Toutes les pages

 

Le module Tkinter

 

Tkinter est un module permettant de réaliser une interface graphique simple pour un programme python.

Il existe de nombreux autres modules à cet effet, mais qui peuvent paraitre complexes pour une introduction à python.

 

Evidemment, la première chose à faire pour utiliser les fonctions du module Tkinter, c'est d'importer de l'importer dans le script :

 

from Tkinter import *

 

Pour bien comprendre la suite, il faut se familiariser un peu avec la notion d'objet.

Oui, oui, c'est bien le même mot que celui qui apparait dans l'expression "Programmation Orientée Objet", mais nous n'allons pas aller aussi loin.

 

Si nous voulons programmer une interface graphique à notre programme, il va falloir définir un objet fenêtre, que je vais nommer mafenetre.

Heureusement, Tkinter permet de définir cet objet très simplement, en effet, il suffit d'écrire :

 

mafenetre = Tk()

 

Voilà, mon objet fenêtre est maintenant créé, et enregistré sous le nom mafenetre.

Maintenant, il y a un certain nombre de méthodes qui peuvent s'appliquer à cette objet, comme par exemple une méthode pour quitter la fenêtre, ce qui s'écrit par exemple :

 

mafenetre.quit()

 

D'une manière générale, pour appliquer une méthode à un objet, la syntaxe à respecter est la suivante ( ne pas oublier le point ! ) :

 

objet.methode()

 

Dans les parenthèses, on peut préciser les options, ou on laisse vide comme dans l'exemple ci-dessus.

 

Une fois cela de compris, on peut à nouveau appliquer ce principe pour créer de nouveaux objets dans la fenêtre mafenetre. On peut notamment créer des bouton ( objet Button ), afficher un texte ( objet Label ), récupérer des données de l'utilisateur ( objet Entry ), faire des dessins ( objet Canvas ), etc...

 

On peut créer autant d'objets que l'on veut dans une fenêtre, mais d'un point de vue pratique, on évite bien sûr de surcharger le tout...

Le seul point important pour chacun de ces objets est de les placer dans la fenêtre mafenetre, sinon ils n'apparaitront pas, ou peut-être même que le script ne se lancera pas.

Il existe pour cela la méthode .pack() et la méthode .grid(). Ma préférence va à la seconde.

 

Voyons cela avec un exemple ( tout ce qui suit les ######### sont des commentaires qui ne seront pas interprétés par le script ) :

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from Tkinter import * ######### Importation du module Tkinter pour créer des fenêtres

mafenetre = Tk() ######### Création d'une nouvelle fenêtre, appellée mafenetre

######### Création d'un « Label » dans mafenetre pour afficher le texte avec couleur de texte ( foreground ) noire
######### et un fond ( background ) jaune. Ce Label s'appelle montexte.

montexte = Label(mafenetre, text='Hello !', fg = 'black', bg='yellow')

######### Affichage de « montexte » avec la méhode .grid(), dans la ligne 0, colonne 0 et à gauche ( West ).
######### La création ne suffit donc pas pour l'afficher.

montexte.grid(row = 0, column = 0, sticky = W)

######### Création et affichage d'un bouton pour fermer la fenêtre.
######### Remarquer la commande mafenetre.quit, on aurait pu mettre n'importe quel nom de fonction à la place.

monbouton = Button( mafenetre, text='Quitter', command=mafenetre.quit)
monbouton.grid(row = 1, column = 1, sticky = E)

######### Enfin, lancer la boucle de réception des événements de fen ( c'est-à-dire l'activer par rapport au
######### clic, au texte clavier, etc... ). Indispensable.

mafenetre.mainloop()

 

tk

 

Ce script est un tout petit exemple, et peut-être qu'en lisant le code, vous aurez compris ce qu'il se passe : le lancement ouvre une petite fenêtre affichant un magnifique texte noir sur fond jaune ( Hello ! ), avec un bouton "Quitter".

Tout simplement extraordinaire.

 

Bon, pour rester sérieux, bien observer les options de création de chaque objet ( Button et Label ) et chaque option utilisées dans la méthode .grid() pour comprendre le positionnement.

Cela ne devrait pas trop poser de problèmes.

 

Le dernier point important, est l'extension du script. Jusqu'à maintenant, nous avons toujours enregistré nos scripts en .py. Pour une interface graphique, on le fera en .pyw ( je vous laisse deviner ce que signifie le "w" ). Si on met une extension .py, le programme s'ouvrira avec une fenêtre DOS en arrière plan. Si c'est pratique pour obtenir les messages d'erreurs pour débugger le programme, ce sera désagréable pour l'utilisateur.

 

Voici un lien vers un site qui propose des screenshots des différents objets habituellement utilisés avec Tkinter : Gnuprog - Tkinter

 

Un autre lien vers une liste complète des widgets ( ou objets ) ainsi que leurs options, en anglais, au format html ou pdf, issu du site officiel :

 

Remarque : Attention au copié-collé du code sur le site. Ici le langage HTML ne reproduit pas les bonnes indentations qui sont essentielles au code python.

 

Exercices :


  1. Ecrire un script python ayant une interface graphique, et permettant de calculer la factorielle d'un nombre qu'un utilisateur aura entré.

On peut envisager deux solutions :

  • la première pour laquelle la réponse s'affichera dans une nouvelle fenêtre,
  • la seconde pour laquelle la réponse s'affichera dans la même fenêtre ( plus difficile ).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# -*- encoding: iso-8859-15 -*-

from Tkinter import *

def factorielle():
n = int(input1.get())
i = 1
while n > 0:
i *= n
n = n - 1

texte = "Le résultat est : " + str(input1.get()) + "! = " + str(i)

resultat = Tk()

texte1 = Label(resultat, text=texte, fg = 'white', bg='black')
texte1.grid(row = 0, column = 1, sticky = W+E, ipadx = 5, ipady = 5)

bouton1 = Button(resultat, text='Quitter', command=resultat.quit, bg='red', fg='white')
bouton1.grid(row = 1, column = 2, sticky = E)

fenetre = Tk()

texte1 = Label(fenetre, text='Entrez le nombre dont vous voulez calculer la factorielle', fg = 'black')
texte1.grid(row = 0, column = 0, sticky = W)

input1 = Entry(fenetre, fg='purple', bg='light blue')
input1.grid(row = 1, column = 1, sticky = W+E, ipadx = 5, ipady = 5)

bouton = Button( fenetre, text='Calculer', command=factorielle, bg='light green', fg='blue')
bouton.grid(row = 3, column = 1, sticky = W)

bouton2 = Button( fenetre, text='Quitter', command=fenetre.quit, bg='red', fg='white')
bouton2.grid(row = 3, column = 2, sticky = E)

fenetre.mainloop()

 

Je ne donne pas de réponse pour le programme ci-dessus dans sa version difficile, je préfère donner la solution dans un autre exemple :

 

  1. En se basant sur le programme Pascal ( en ligne de commande ) fait en cours, réaliser un programme python avec interface graphique dans lequel l'utilisateur entre un nombre entier n, et qui affiche le triangle de Pascal dans la même fenêtre jusqu'à la ligne n.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# -*- encoding: iso-8859-15 -*-

from Tkinter import *
from tkFont import *

def factorielle(nb):
prod = 1
while ( nb > 1 ):
prod = prod * nb
nb = nb - 1
return prod


def combinaison(nb, total):
return factorielle(total) / ( factorielle(nb) * factorielle(total - nb) )


def pascal(event):
k = int(input1.get())
texte = ""
j = 0
while ( j <= k ):
i = 0
while ( i <= j ):
texte = texte + " " + str(combinaison(i,j))
i = i + 1
texte = texte + "\n\n"
j = j + 1
blabla.configure(text = "Voici le triangle de Pascal jusqu\'à " + str(k) + "\n", fg='yellow', bg='gray', font=("Times", "24", "bold italic"))
resultat.configure(text = texte, fg='green', bg='black', font = ("Times", "16"))

fenetre = Tk()

texte1 = Label(fenetre, text='Afficher le triangle de Pascal jusqu\'a combien ?', fg = 'black')
texte1.grid(row = 0, column = 1, sticky = W+E)

input1 = Entry(fenetre, bg='white', fg='red')
input1.bind("<Return>", pascal)
input1.grid(row = 1, column = 1, sticky = W+E, ipadx = 5, ipady = 5)

blabla = Label(fenetre)
blabla.grid(row = 2, column = 1, sticky = W+E, ipadx = 5, ipady = 5)

resultat = Label(fenetre)
resultat.grid(row = 3, column = 1, sticky = W+E, ipadx = 5, ipady = 5)

bouton2 = Button( fenetre, text='Quitter', command=fenetre.quit, relief='groove')
bouton2.grid(row = 4, column = 2, sticky = W)

fenetre.mainloop()

 

Quelques remarques à propos de la solution proposée :

  • On importe au début le module tkfont pour s'amuser un peu les l'affichage des polices ( analyser le code pour comprendre où ),
  • les trois fonctions définies au début sont celles que nous avions déjà rencontré dans l'exercice sur le triangle de Pascal, il y a une grosse différence dans la définition de la fonction pascal, que j'expliquerai plus tard,
  • comme d'habitude, les fonctions ne sont pas lancées tant qu'on ne les appelle pas, donc après l'importation des modules, la première chose qui sera effectuée sera de construire la fenêtre,
  • on définit donc une fenêtre contenant un widget d'entrée pour l'utilisateur, deux widgets Label pour l'affichage de texte et de la réponse, et un widget bouton pour quitter le programme,
  • une action est reliée à la fenêtre d'entrée grâce à la méthode .bind : dès que l'on appuie sur la touche entrée ( <Return> ), le programme "pascal" est lancé. On aurait très bien pu concevoir le programme avec un bouton pour lancer la fonction "pascal". Pour que l'événement sur la touche entrée soit "actif", il FAUT que l'argument de la fonction pascal soit "event",
  • nous avons ajouté dans la fonction pascal les lignes "blabla.configure(...)" et "resultat.configure(...)". La méthode .configure permet de reconfigurer les widgets, et ici en l'occurrence de mettre à jour les textes des labels blabla et resultat.

 

Un dernier point que j'aimerais aborder : comment insérer une image ?

 

On peut pour cela utiliser le widget Canvas et la classe PhotoImage qui permet d'importer des images. Le seul problème, c'est que l'on est restreint sur le choix des extensions : cela ne fonctionne pas avec jpg et png, mais avec gif ( pour jpg et png, il faudra utiliser par exemple le modul PIL ).

 

Une fois une fenêtre "fenetre" créée avec Tk(), on y créé un widget canvas, on créé un objet image associé à l'image qui se nomme 1.gif grâce à la fonction PhotoImage et on importe cette image dans le canvas grâce à la méthode .create_image :

 

 

can = Canvas(fenetre, width=800, height=600, bg='#07e0e3')
maphoto = PhotoImage(file='1.gif')
photo=can.create_image(400,300, image=maphoto)
can.grid(row = 1, column = 1, sticky = W+E)

 

 

Si l'on veut changer l'image dans le canvas, on peut utiliser la méthode .itemconfigure.

 

 



Mise à jour le Jeudi, 06 Mai 2010 12:09