Zhentao Li's Homepage

email:zl zli2 com

 // home


Interface graphique

Module Tkinter

Plusieurs modules existe pour la créations d'interfaces graphiques. Parmis ceux-ci, Tkinter est inclus dans toutes les versions de Python et n'a donc pas besoin d'installation séparée.

import Tkinter as tk

Si vous avez IPython (normalement inclus dans l'installation de Jupyter du cours dernier), il est possible de voir l'interface créée à fur et mesure, ligne par ligne. Sinon, il faut attendre la dernière ligne avant de voir le tout se matérialiser.

Un exemple:

In [1]: import Tkinter as tk
In [2]: racine = tk.Tk()
In [3]: etiquette = tk.Label(racine, text='Bonjour')
In [4]: etiquette.pack()
In [5]: bouton = tk.Button(racine, text='Quitter', command = racine.destroy)
In [6]: bouton.pack()
In [7]: racine.mainloop()

Widgets Tkinter

Tkinter inclut les composantes à partir duquel vous pouvez construire votre interface, chacun représenté par une classe. Il est conseillé de lire les ressources sur la page du TP plutôt que le help de ces classes.

Ces morceaux d'interface sont appellés « widgets ».

Button: Button qui exécute un fonction lorsqu'on appui dessus.

Checkbutton: Case à cocher.

Entry: Champs d'entrée texte.

Menu: Un menu déroulant ou bien un menu pop up

Label: Étiquette contenant du texte (ou une image).

Radiobutton: Permet de choisir une valeur parmi plusieurs possibilités.

Tk: « Racine » de l'application graphique. C'est aussi la première fenêtre.

Toplevel: Une autre fenêtre qui n'est pas la « racine ».

Widgets un peu plus complexes

Canvas: Un espace pour disposer divers éléments dessinés (lignes, cercles, rectangles, etc).

Menubutton: Un bouton-menu, à utiliser pour les menus déroulants.

Listbox: Une liste de choix proposés à l’utilisateur.

Scrollbar: Barre de défilement

Text: Affichage de texte formatté. Permet aussi à l’utilisateur d’éditer le texte affiché.

Emplacement

Maintenant que nous avons vu quelques widgets de base, il faut spécifier où ils sont placé les uns par rapport aux autres.

L'emplacement voulue des widgets peut être décrite de trois façons différentes:

  1. En utilisant Frame, qui est un contenant de d’autres widgets. Il suffit d'emboîter les Frames et passer les bons paramètres à la méthode pack pour obtenir l'organisation voulue.
  2. Utiliser la méthode place à la place de pack pour placer un élément à un endroit exacte.
  3. grid permet de disposer par coordonnées l'emplacement des widgets dans une grille.

Exemple Frame et pack

import Tkinter as tk
racine = tk.Tk()
premier = tk.Label(racine, text='premier')
premier.pack(side='top')
deuxieme = tk.Label(racine, text='deuxième')
deuxieme.pack(side='top')
troisieme = tk.Frame(racine)
troisieme.pack(side='top')
gauche = tk.Label(troisieme, text='gauche')
gauche.pack(side='left')
milieu = tk.Label(troisieme, text='milieu')
milieu.pack(side='left')
droite = tk.Label(troisieme, text='droite')
droite.pack(side='left')
racine.mainloop()

Remarque: Le premier paramètre donné lors de la création d'un widget est le widget qui devrait contenir celui-ci.

Les valeurs possible pour side= sont 'top', 'left', 'right', 'bottom'. Ici, les widgets contenus dans un Frame (ou Tk ou Toplevel) sont distribués uniformément. Pour voir les autres options possibles, lire le help(tk.Label.pack) ou les documents de référence.

Remarque (avancé): D'avoir mis pack comme méthode du widget contenu (plutôt que le widget contenant) est atypique de Python et est un vestige du langage Tcl/Tk. Le module Tkinter de Python est une interface vers les fonctions de ce langage.

Exemple place

Si on ajoute ces deux lignes avant la fin du mainloop dans l'exemple précédent, on verrait le nouveau Label ajouté par dessus le reste.

flottant = tk.Label(racine, text='flottant')
flottant.place(x=10, y=20)

Ici, nous appelons la méthode place à la place de pack.

Exemple grid

Nous pouvons aussi appeller la méthode grid à la place de pack.

import Tkinter as tk
racine = tk.Tk()
premier = tk.Label(racine, text='premier')
premier.grid(row=1, column=1)
deuxieme = tk.Label(racine, text='deuxième')
deuxieme.grid(row=3, column=2)
troisieme = tk.Label(racine, text='trosième')
troisieme.grid(row=2, column=3)
racine.mainloop()

Il est déconseiller d'utiliser grid et pack ensemble dans un même contenant (Frame, Tk ou Toplevel).

Actions de l'utilisateur

Pour exécuter une fonction lorsque l'utilisateur appuie sur la touche Entrée sur un widget Entry, nous pouvons utiliser la

import Tkinter as tk

def touche_entree(widget):
    # Affiche le contenu entré
    print entry.get()

racine = tk.Tk()
entry = tk.Entry(racine)
entry.pack()
entry.bind('<Return>', touche_entree)
racine.mainloop()

bind

bind peut aussi associer une fonction aux clicks et movements de la souris, etc. Voici une liste des possibilité obtenue d'ici

Nom Signification
<KeyPress> Pression sur n'importe quelle touche
<KeyPress-a> Pression sur la touche ‘A’ (minuscule)
<KeyPress-A> Pression sur la touche ‘A’ (majuscule)
<Return> Pression sur entrée
<Escape> Touche d’échappement
<Up> <Down> Pression sur les flèches
<Button-1> Click souris gauche
<Button-2> Click souris milieu (ou gauche et droite)
<Button-3> Click souris droit
<ButtonRelease> Fin de click gauche
<Motion> Mouvement de la souris
<B1-Motion> Mouvement de la souris avec click gauche
<Enter> <Leave> Entrée et sortie souris d’un widget
<Configure> Redimensionnement de la fenêtre
<Map> <Unmap> Ouverture et iconification de la fenêtre

Idée du fonctionnement en général

Lorsqu'une action est prise par l'utilisateur, l'idée est de récupérer la valeur des états et selon l'action, engendrer l'effet voulue.

Cette méthode de fonctionnement, où l'on réagit à des actions par des appels à des fonctions porte le nom de programmation évènementielle.

Question (avancée): Comment est-ce que la programmation évènementielle est possible? Nous savons que les programmes sont pourtant exécutés ligne par ligne.

Références

Pour une liste plus exhaustive des fonctions de Tkinter et des paramètres que l'on peut leur passer.


Website design modified from Sliqua taken from OSWD