Vous êtes sur la page 1sur 8

1.

Créer des interfaces graphiques en Python avec


Tkinter
Tkinter (pour Tool kit interface) est une boîte à outils d'interface graphique pour Python. Le
module Tkinter s'installe avec Python et est présent par défaut.
Il suffit donc d'importer le module au début d'un script.

1.1. Créer une fenêtre pour une application


Les instructions de bases sont les suivantes :
À placer en début de script ; le programme va aller chercher toutes les
from tkinter import * fonctions disponibles dans le module Tkinter (on peut cibler cette
importation aux uniques éléments nécessaires à l'application : voir ci-
dessous pour ces éléments)
Fenetre = Tk() instruction de création de la fenêtre ; on peut bien sur utiliser le nom que
l'on veut à la place de "Fenetre" !
Fenetre.title('Fenêtre sur
cours ( de Python )') Donne un titre à la fenêtre (par défaut c'est "tk")

Lance la boucle principale : le programme tournera « en boucle » en


attendant des actions de l’utilisateur. A placer à la fin de la création de
l'interface.

Fenetre.mainloop()

Travail à faire 1

Commencer à écrire le script précédent pour vous familiariser avec ces notions de base.

1.2. Les widgets


widget : contraction de l'anglais windows gadget ("gadget de fenêtre").
"widget" est le terme général utilisé pour désigner tous les objets graphiques que l'on peut insérer
dans une interface (fenêtre).

Les widgets situés à l'intérieur d'une fenêtre sont les enfants de celle-ci; inversement, la fenêtre
est la parente des widgets.

Les principaux sont :

 Les boutons : Button ( bouton pour commander une action)


 Les labels : Label ( étiquette pour insérer un texte)
 Les zones de saisie : Entry ( champ de saisie utilisateur pour
permettre l'entrée d'une donnée)
Chaque widget a des propriétés et des fonctions qui permettent de régler son apparence et les
interactions avec l'utilisateur.
Chaque widget (objet d'interface) doit être créé puis placé dans la fenêtre

Le widget Button

Syntaxe :
nom du widget = Button(nom de la fenêtre parente, text = "texte à afficher dans
le bouton", command = nom de la fonction à appeler lors d'un clic sur le bouton )

Exemple :
bouton = Button( Fenetre , text = "quitter", command = Fenetre.destroy) #
Création du bouton
bouton.pack() # Affichage du bouton dans la fenêtre

 Ce qui sera affiché sur le bouton est contenu dans la propriété text.
 La fonction appelée par command permet une action lorsqu'on clique sur le bouton.
Cette fonction peut être choisie parmi les fonctions intégrées au système, ou celles définies
dans le programme ( lancer d'un calcul, affichage d'une image,...)
Ici, la commande système Fenetre.destroy() est une fonction qui "détruit" l'objet nommé
" Fenetre " en mémoire. La pression du bouton a donc ici pour conséquence la fermeture de
la fenêtre nommée "Fenetre".

On remarque donc que la création d'un widget se fait en deux temps : création en mémoire
( première instruction ), puis affichage ( instruction .pack() ).

Le widget Label

Syntaxe :
nom du widget = Label(nom de la fenêtre parente, text = 'texte à afficher' , fg
= 'couleur du texte', bg = 'couleur du fond' )

Exemple :
texte = Label( Fenetre, text = "Hello World",fg = 'black', bg = 'white') #
Création d'un label avec un texte noir sur fond blanc
texte.pack() # Insertion du label dans la fenêtre

Les couleurs du label ( fg = foreground = premier plan ) et de fond ( bg = background> = arrière-


plan ) sont à indiquer en anglais !
D'autres propriétés existent, et sont également modifiables ( police du texte, taille des
caractères,...)

Le widget Entry

Syntaxe :
nom du widget = Entry( nom de la fenêtre parente )

Exemple :
Entree = Entry( Fenetre ) # Création d'un champ de saisie nommé "Entree"
Entree.pack()# insertion du champ dans la fenêtre "Fenetre"
Positionnement des widgets dans la fenêtre

L'instruction pack() utilisée précédemment sans précision place par défaut les widgets les uns en
dessous des autres dans la fenêtre; il existe bien entendu une manière plus "fine" de gérer ce
positionnement.

Tkinter dispose en fait de plusieurs gestionnaires de placement pour les widgets :

 le gestionnaire pack() déjà vu précédemment : souvent difficile à maîtriser car pas très
intuitif...
 le gestionnaire grid() : beaucoup plus simple à manipuler, puisqu'il suffit de voir la fenêtre
comme une grille, dans laquelle on positionne les widgets en indiquant à quelle ligne
( row ) et à quelle colonne ( column ) il doit se positionner.

Exemple :
# création des widgets
bouton1 = Button(ma_fenetre, text = "Bouton 1")
bouton2 = Button(ma_fenetre, text = "Bouton 2")
etiq = Label(ma_fenetre, text = "Etiquette")

# positionnement des widgets


bouton1.grid(row = 0, column = 2 )
bouton2.grid(row = 2, column = 1 )
etiq.grid(row = 1, column = 0)

Travail à faire 2

Vous allez réaliser une interface graphique assez simple ayant l'aspect ci-dessous :

 l'interface ne contient qu'un seul bouton et deux étiquettes.


 une des étiquettes est placée juste à droite du bouton, et ne contient aucun texte au
démarrage du programme; si l'utilisateur clique sur le bouton ( ce qu'il ne devrait bien sur
normalement pas faire...), le texte des étiquettes doit changer...

Quelques indications :

Pour changer le texte d'une étiquette, il faut utiliser avec Tkinter une variable de contrôle; il s'agit
d'une variable qui sera liée à un ou plusieurs widgets, et qui pourra être lue ou modifiée; la
modification se "propagera" alors dans tous les widgets auxquels elle est liée...

Pour créer une variable de contrôle :


score = IntVar() # variable de contrôle contenant des valeurs numériques
mot = StringVar() # variable de contrôle contenant des chaînes de caractère
Pour "lier" la variable de contrôle à un widget, il faut utiliser la propriété textvariable :
score = IntVar()
label_score = Label ( fen , textvariable = score )

Enfin, pour lire ou pour modifier une variable de contrôle :


score.get() # permet de lire le contenu de la variable de contrôle
mot.set('bla bla bla') # permet de modifier le contenu de la variable de
contrôle

1.3. Pour aller plus loin...


 Une documentation (http://tkinter.fdex.eu/index.html ) claire et concise présentant tous les
widgets de Tkinter.
 la page (http://fsincere.free.fr/isn/python/cours_python_tkinter.php ) consacrée à Tkinter
sur le site de Fabrice Sincère. Présente de nombreux exemples.

Il existe de très nombreux widgets, chacun ayant un certain nombre d'options; impossible de tous
les documenter ici. Il faudra donc souvent que vous fassiez vos propres recherches
d'informations pour utiliser telle ou telle notion liée à Tkinter...

2. Gestion des images dans Tkinter


Tkinter comprend par défaut des fonctions de gestion d'image, mais qui se limitent aux seuls
formats GIF et PGM/PPM de type brut ( et pas ASCII ).
Pour la manipulation d'autres formats, il faut utiliser le module PIL ( Python Image Library )
après l'avoir importé. ( Ce module n'est pas installé de base avec Python, il faut généralement le
rajouter par la suite )

2.1. Ouverture d'une image


Principe

L'intégration d'une image suit le schéma suivant :

 ouverture d'un fichier GIF ou PGM :


 mon_image = PhotoImage(file = "image.pgm")

Les pixels de l'image se trouvent alors stockés dans la variable mon_image.

 détermination des dimensions de l'image :


 largeur = mon_image.width() # dimensions en nombre de pixels
 hauteur = mon_image.height()

 création d'un widget ( canevas, étiquette ) dans lequel l'image sera affichée :
 zone_image = Canvas(Fenetre, width = largeur, height = hauteur) # crée un
canevas de dimensions ajustées à celles de l'image
 zone_image.create_image(0,0, anchor = NW, image = mon_image) # association
image/widget
 zone_image.pack() # placement du widget

'0,0' indique les coordonnées du point de la fenêtre où sera affichée l'image ( ici, en haut à
gauche ).
La propriété anchor permet d'indiquer quel coin de l'image sera ancrée en ce point ( ici :
North-West = haut-gauche )

Travail à faire 3

Écrire un script qui affiche une image GIF ou PGM/PPM dans une fenêtre
Tkinter.

2.2. Manipulation des pixels


Lecture de la valeur d'un pixel :
pixel = mon_image.get(x,y)

Deux choses très importantes à avoir à l'esprit :

1. les coordonnées du pixel sont données en indiquant d'abord son


abscisse, puis son ordonnée; c'est l'inverse du mode opératoire
utilisé avec les listes de listes, où l'on donne d'abord le numéro de
ligne ( = y ) puis celui de la colonne ( = x )...Le point (0,0), origine
des coordonnées, est le coin haut-gauche de l'image.
2. Attention, l'information renvoyée ( ici stockée dans la
variable pixel ) est en fait constituée d'un "bloc" de 3 valeurs, codant
chacune le Rouge, le Vert et le Bleu. Un tel bloc s'appelle en Python
un tuple.
Un tuple est défini en Python par des parenthèses ( ici : (r, v , b) ),
et les éléments d'un tuple ne sont pas modifiables.
L'index de chaque élément est précisé de manière analogue à celui
utilisé avec les listes.
pixel = mon_image.get(56,23)
print(pixel)
>>> ( 122 , 235 , 46)

print(pixel[1])
>>> 235

Modification de la valeur d'un pixel :

Les informations devant être formatées d'une manière particulière, on utilisera la syntaxe suivante
sans se poser trop de questions :
photo.put("#%02x%02x%02x" % pixel, (x,y))

pixel doit être un tuple de 3 valeurs cohérentes avec le codage des couleurs de l'image ( pour une
image en niveaux de gris, ces 3 valeurs doivent donc être identiques...)
Même remarque que ci-dessus pour le système de coordonnées (x,y) utilisé.

2.3. Une interface pour le traitement d'images


Vous allez maintenant "recoller" les bouts de scripts que vous avez écrits jusqu'à maintenant, dans
l'objectif de réaliser une interface pour les fonctions de traitement d'images que vous avez écrites
précédemment.

L'interface pourrait se présenter de la façon suivante :

Les boutons appelleront les différentes fonctions de traitement de l'image; vous pourrez en
rajouter bien entendu, mais commencez d'abord à en faire fonctionner un !!

Pour définir la valeur du seuil, on utilise ici une échelle de valeurs, correspondant au
widget Scale. Vous pouvez expérimenter d'autres possibilités, le widget SpinBox pourrait aussi
convenir...

Pensez également à améliorer un peu le positionnement des différents widgets.

3. Projet Tkinter : le jeu de morpion (travail à faire


4)
...que vous connaissez bien sûr tout très bien...

L'objectif est donc de créer en Python et à l'aide de Tkinter, un jeu de morpion, jouable à deux
joueurs ou contre l'ordinateur; une ébauche "d'intelligence artificielle" devra donc être développée
pour ça !

Mais vous procéderez bien entendu par étapes :

 dans un premier temps, vous créerez l'interface graphique de votre jeu, à savoir une simple
grille de 3 cases x 3 cases dessinée sur un canevas Tinter ( Rappel : il s'agit d'un widget
correspondant à une "zone de dessin").
 une fois le "plateau de jeu" créé, vous coderez le jeu en lui-même, en vous restreignant à un
jeu joueur contre joueur; votre script devra donc gérer l'affichage d'un rond ou d'une croix
selon le joueur et l'endroit où il aura cliqué dans le jeu.
 ensuite, vous coderez les instructions qui permettent au script de
déterminer à chaque tour de jeu si un des joueurs est gagnant, c'est à
dire a aligné 3 symboles identiques.
 une fois que tout ceci fonctionnera, vous pourrez alors réfléchir à un
jeu « joueur contre PC »...

3.1. Plateau de jeu


Le plateau de jeu est constitué de 2 lignes verticales et 2 horizontale, tracées sur un canevas dans
une fenêtre Tkinter.

Écrire le script qui crée ce plateau de jeu.

Pour créer un canevas ( zone de dessin ) dans une fenêtre :


nom_du_canevas = Canvas(fenêtre_parente, width = largeur, height = hauteur)

Pour tracer une ligne sur un canevas, utiliser la méthode create_line() :


can.create_line(xorigine , yorigine , xfin , yfin , fill = 'couleur', width = épaisseur)

Attention, l'origine du repère pour les coordonnées dans un canevas Tkinter


est en haut à gauche du canevas

3.2. Placement des symboles


Le script doit maintenant gérer le placement des symboles, à savoir une croix ou un
rond alternativement selon le joueur 1 ou 2.

Votre script doit donc "intercepter" les clics souris et pouvoir déterminer la
position du curseur de la souris au moment du clic : on parle pour cela
d'évènements souris. Il existe de même des évènements clavier ( non abordés
ici ).
Deux choses sont nécessaires :

Lier un gestionnaire d'évènements à un widget

Un gestionnaire d'évènement est l'ensemble des instructions qui seront


exécutées lorsqu'un évènement particulier se produit; pour que cela fonctionne, il faut que le
script puisse être en mesure de détecter quand cet évènement se produit; pour cela, on doit lier le
gestionnaire d'évènement à un des widgets de l'interface.

On utilise la syntaxe suivante après avoir créé le widget :


nom_du widget.bind('<évènement>' , gestionnaire_d_évènement)

Les évènements utilisables avec la souris sont par exemple : '<Button-1>' pour la détection du
clic gauche, '<Button-2>' pour le clic droit, etc...

Exemple : pour lier à un canevas nommé can un gestionnaire d'évènement


nommé gestion_clic pour détecter le clic-gauche de la souris, on écrira :
can.bind('<Button-1>' , gestion_clic)
Le gestionnaire d'évènements

Le gestionnaire en lui-même est une fonction qui sera automatiquement appelée lorsque
l'évènement se produit; cette fonction ne peut recevoir qu'un seul argument, l'évènement en lui-
même stockée dans une "variable" nommée evt.

Par exemple, on écrira :


def gestion_clic(evt):
......
......

Pour récupérer ensuite par exemple les coordonnées du curseur de souris :


curseur_X = evt.x # abscisse du curseur dans le canevas
curseur_Y = evt.y # ordonnée du curseur

Pour tracer un cercle sur un canevas, utiliser la méthode create_oval() :


can.create_oval(xorigine , yorigine , xfin , yfin , outline = 'couleur', width =
épaisseur)

...où les coordonnées x,y correspondent ici à celles des coins du carré dans lequel le cercle est
inscrit.

3.3. Y a-t-il un gagnant ?


Il ne vous reste plus qu'à écrire les instructions qui permettront, à
chaque tour de jeu, de déterminer si un des joueurs a gagné.

Pour cela, il faut pouvoir tester les possibilités (il y en a 8 en tout )


pour un joueur d'avoir aligné 3 symboles identiques...

Puis, le joueur 2 débute...

3.4. Une IA élémentaire...


Si vous avez terminé avant … à poursuivre et à réfléchir…

Vous aimerez peut-être aussi