Tkinter - j.galtier

advertisement
Module graphique Tkinter pour Python
Tkinter est le module graphique de base du langage python. Ce n'est pas le seul, par exemple, wxPython, PyQt
ou PyGTK. Les exemples ci-dessous sont fonctionnels sur Debian.
1. Utilisation du module Tkinter
1.1 Charger le module
1.2 Ouvrir une fenêtre
1.3 Lancer le script
2. Les widgets simples
2.1 'Label'
2.2 'Text'
2.3 'Entry'
2.4 'Button'
2.5 'Checkbutton'
2.6 'Radiobutton'
3. L'espace graphique Canvas
3.1 Afficher une image
3.2 Rectangle, ellipse et quartier
3.3 Ligne et point
3.4 Polygones
3.5 Texte graphique
3.6 Reconfigurer un objet
4. Fenêtres, cadres et panneaux
4.1 TopLevel
4.2 Frame
4.3 PanedWindow
5. Listes et menus
5.1 Listbox
5.2 Scrollbar
5.3 Menu
7. Styles
7.1 Couleurs
7.2 Alignements
7.3 Reliefs
7.4 Fontes
8. Modules associés
8.1 Boîtes à message
8.2 Boîtes de saisie
8.3 Sélecteurs de fichier
8.4 Sélecteurs de couleur
9. Documentation
9.1 dans le logiciel
9.2 sur le système GNU+Linux
9.3 sur Internet
9.4 sur papier
1. Utilisation du module 'Tkinter'
Tout d'abord, le module Tk pour python doit être installé. Pour Debian-Lenny: apt-get install python-tk
1.1 Charger le module
Pour utiliser le module Tkinter, il faut d'abord choisir un mode de chargement:
import Tkinter charge tout le module, dont le nom doit précéder toute fonction: racine=Tkinter.Tk().
import Tkinter as tk permet d'utiliser un alias: racine=tk.Tk()
from Tkinter import * permet d'utiliser toutes les fonctions sans préciser le nom du module: racine=Tk()
Dans cette page, par souci de clarté, le module Tkinter sera toujours explicite et les variables seront en français et
en minuscules.
1.2 Ouvrir une fenêtre
L'utilisation d'une fenêtre se résume schématiquement à cette procédure (les majuscules sont toujours
importantes):
#! /usr/bin/python import Tkinter racine=Tkinter.Tk()
racine.geometry("400x300") racine.mainloop()
Tk() permet de désigner un premier objet (une fenêtre) duquel les autres dépendront, son nom est ici 'racine'.
racine.mainloop() lancera le gestionnaire d'événements. Les fonctions graphiques doivent se situer entre les
deux. racine.geometry("400x300") permet de préciser la taille de la fenêtre.
1.3 Lancer le script
Tous les exemples proposés sont fonctionnels. Pour qu'ils puissent fonctionner sur UNIX, ne pas oublier
#! /usr/bin/python sur la première ligne (s'assurer que le logiciel python se situe bien à cette adresse),
sauvegarder le script et le rendre exécutable, par exemple avec chmod 755 votre-fichier.py.
Avec un système UNIX bien configuré, un double-clic sur l'icone peut lancer un script "graphique", mais il est
préférable, lors du développement, de le lancer dans une console: ./nom-du-script.py afin de voir les éventuels
messages d'erreur.
2 Les widgets simples
'widget' signifie 'bidule'. Il s'agit d'éléments simples, comme un titre, un bouton, un texte, un champ éditable... ou
plus complexes, comme un système de menus.
2.1 'Label'
'Label' permet un affichage simple de texte:
import Tkinter racine=Tkinter.Tk() texte=Tkinter.Label(racine,
text="Premier texte\ndans une fenetre", fg="black")
texte.pack(side=Tkinter.RIGHT) racine.mainloop()
side=Tkinter.RIGHT permet de placer la chaîne de caractère à droite de la fenêtre
Label peut également recevoir une image sous format .gif:
import Tkinter racine=Tkinter.Tk()
dessin=Tkinter.PhotoImage(file="nomdefichier.gif")
label=Tkinter.Label(image=dessin) label.pack() racine.mainloop()
2.2 'Text'
'Text' définit une plage permettant l'insertion et la manipulation d'un texte.
import Tkinter racine=Tkinter.Tk() texte=Tkinter.Text(racine, width=25,
height=5) texte.insert(Tkinter.END,'Un texte ins\xe9r\xe9')
texte.pack(side=Tkinter.RIGHT) racine.mainloop()
'width' est la largeur de la plage en nombre de caractères, 'height' le nombre de lignes.
RIGHT concerne la plage de texte: en agrandissant la fenêtre, on verra que la plage se situe à droite, même si le
texte est aligné à gauche. RIGHT est une variable du module, il faut donc la précéder du nom de celui-ci avec le
mode d'importation du module qu'on a choisi.
2.3 'Entry'
'Entry' permet de saisir un texte. Il faut donc prévoir une variable permettant de recevoir le texte saisi.
import Tkinter racine=Tkinter.Tk() texte=Tkinter.Label(racine,
text='Cliquer et saisir:', width=20, height=3, fg="black") texte.pack()
saisir=Tkinter.StringVar() # prevoir la variable pour recevoir le texte
saisi saisie=Tkinter.Entry(textvariable=saisir, width=30) saisie.pack()
racine.mainloop() print saisir.get() # on recupere et affiche le texte
saisi
On peut recevoir une variable numérique avec IntVar().
2.4 'Button'
'Button' définit un bouton cliquable
import Tkinter racine=Tkinter.Tk() bouton=Tkinter.Button(racine,
text="Quitter", command=racine.quit) bouton.pack(side=Tkinter.BOTTOM)
racine.mainloop()
side peut également prendre les valeurs LEFT, RIGHT, TOP ou CENTER
2.5 'Checkbutton'
'Chekbutton' est une "case à cocher". Une méthode est proposée pour récupérer l'information sur l'état de la "case
à cocher".
import Tkinter racine=Tkinter.Tk() retour=Tkinter.IntVar() # on cree une
variable pour l'etat de la case a cocher bouton=Tkinter.Checkbutton(racine,
variable=retour, text="Cochez-moi") bouton.pack() racine.mainloop() # la
valeur est recuperee lors de la sortie de la fenetre: if retour.get() == 0:
# la variable 'retour' reste a 0 si la case est restee intacte
print
"Vide!" else:
print "Tilt!"
2.6 'Radiobutton'
RadioButton est un ensemble de Checkbutton exclusifs pour une même variable. La variable option rendra la
valeur proposée par 'value' du bouton sélectionné.
import Tkinter racine=Tkinter.Tk() retour=Tkinter.IntVar() # on cree une
variable pour la valeur liee a la case cochee
bouton1=Tkinter.Radiobutton(racine,text="Oui", variable=retour, value=2)
bouton2=Tkinter.Radiobutton(racine,text="Non", variable=retour, value=3)
bouton3=Tkinter.Radiobutton(racine,text="P-\xea", variable=retour, value=7)
bouton1.grid() bouton2.grid() bouton3.grid() racine.mainloop() print
retour.get() # retourne 2, 3 ou 7 selon le bouton choisi, ou 0 si pas de
choix
Il est possible de définir des valeurs-retours sous forme de chaîne (value="bof") et en précisant
retour=Tkinter.StringVar()
3 L'espace graphique Canvas
Canvas crée une surface sur laquelle on peut placer des éléments graphiques:
import Tkinter racine=Tkinter.Tk() fond=Tkinter.Canvas(racine, width=300,
height=200, background='darkgray') fond.pack() ... # votre script
racine.mainloop()
Pour les fonctions qui suivent, 'fill' permet la définition d'une couleur (même pour 'creat_text'), 'width'
l'épaisseur, 'outline' la couleur du bord; les objets seront placés par "anchor".
3.1 Affichier une image
Manière d'insérer une image .gif:
import Tkinter racine=Tkinter.Tk() photo=Tkinter.PhotoImage(file="votreimage.gif") # ouverture de l'image largeur=photo.width();
hauteur=photo.height() # determination des dimensions
racine.geometry(str(largeur+2)+'x'+str(hauteur+2))
racine.title(str(largeur)+'x'+str(hauteur)) fond=Tkinter.Canvas(racine,
bg='black') fond.pack()
img=fond.create_image(largeur/2+1,hauteur/2+1,image=photo)
racine.mainloop()
3.2 Rectangle, ellipse et quartier
Pour fond représentant l'ouverture d'un canevas:
rect=fond.create_rectangle(140,40,280,90, fill='white', outline='red',
width=10) ellipse=fond.create_oval(30,120,150,180, fill='green',
outline='blue', width=5)
fond.create_arc(x1,y1,x2,y2,start=depart,extent=extension,style=Tkinter.PIE
SLICE)
Les deux premiers entiers représentent les coordonnées du point en haut à gauche du rectangle, les deux suivants
celles du point en bas à droite. Pour 'create_oval' et 'create_arc', il s'agit des coordonnées du rectangle circonscrit.
Pour 'create_arc', l'angle de départ et l'extension sont donnés en degrés (progression anti-horaire).
Tkinter.CHORD limite la surface entre la partie d'arc et sa corde.
3.3 Lignes et points
Avec fond représentant l'ouverture d'un canevas:
ligne=fond.create_line(160,190, 250,110, 270,170, 180,120)
Les arguments commencent par des paires qui sont des coordonnées de points.
smooth=True si une ligne brisée doit être courbée (spline)
splinesteps=12 pour un lissage de la courbe si smooth=True
capstyle=Tkinter.BUTT , ROUND ou PROJECTING
arrow=Tkinter.BOTH place une flèche aux bouts de la ligne (Tkinter.FIRST pour le départ, Tkinter.LAST pour
la fin)
arrowshape=(8,10,3) permet de modifier la longueur de la flèche, la longueur des branches et la largeur.
Pour afficher le point x,y, il faut afficher une ligne qui va de x,y à x+1,y+1 (le dernier point d'une ligne n'est pas
affiché).
3.4 Polygones
Pour fond représentant l'ouverture d'un canevas:
polygone=fond.create_polygon(35,105, 120,85, 95,25, 80,75, 25,60, 65,30,
fill="cyan", width=5, outline='black')
Les arguments commencent par des paires qui sont des coordonnées de points. Il n'est pas nécessaire de répéter
les coordonnées du premier sommet.
smooth=True si le pourtour doit être arrondi
splinesteps=12 pour un lissage de la courbe si smooth=True
3.5 Texte graphique
Pour positionner un texte au pixel près sur un canevas:
txt=fond.create_text(15, 25, text="Spam?", font="Arial 16 italic",
fill="gray")
Rappel: la couleur du texte est définie ici par 'fill'!
3.6 Reconfigurer un objet
L'instance récupérée lors de la création a une importance, car elle permet de manipuler les objets créés:
fond.itemconfigure(ellipse,fill="green") # l'objet 'ellipse' est (re)colore
en vert fond.delete(rectangle1) # detruit un objet appele 'rectangle1'
Exemple (changement de couleur lié au clic sur un bouton):
#! /usr/bin/python import Tkinter racine=Tkinter.Tk()
fond=Tkinter.Canvas(racine, width=300, height=200, background='darkgray')
fond.pack() rectangle=fond.create_rectangle(50,50,250,150, fill='blue')
def Rougit():
fond.itemconfigure(rectangle,fill='red')
bouton=Tkinter.Button(racine,text="Rouge!", command=Rougit) # fonction sans
guillemets! bouton.pack() racine.mainloop()
4. Fenêtres, cadres et panneaux
4.1 'TopLevel'
TopLevel permet l'ouverture d'une nouvelle fenêtre. Afin de ne pas surcharger l'exemple, la nouvelle fenêtre
n'affiche rien de plus que la première.
import Tkinter racine=Tkinter.Tk() racine.title("Principale")
fenetre=Tkinter.Toplevel() fenetre.title("Seconde") fenetre.grid()
racine.mainloop()
Deux fenêtres vont s'ouvrir: la principale, nommée pour l'occasion 'Principale', et la seconde, appelée 'Seconde'.
On subordonne le plus souvent la création d'une seconde fenêtre à un événement de la première, par exemple
associée au clic d'un bouton.
4.2 'Frame' et 'LabelFrame'
Frame est un cadre, permettant de regrouper géographiquement les widgets dans une fenêtre.
import Tkinter racine=Tkinter.Tk() Cadre=Tkinter.Frame(racine)
bouton1=Tkinter.Button(Cadre,text="Bouton 1")
bouton2=Tkinter.Button(Cadre,text="Bouton 2")
bouton3=Tkinter.Button(Cadre,text="Bouton 3")
bouton1.pack(side=Tkinter.LEFT) bouton2.pack(side=Tkinter.TOP)
bouton3.pack() Cadre.pack() racine.mainloop()
Il est possible de donner un bord et un nom à un cadre avec LabelFrame:
Cadre=Tkinter.LabelFrame(racine,text="Titre de cadre")
4.3 'PanedWindow'
PanedWindow permet de diviser une fenêtre en plusieurs panneaux adaptables.
import Tkinter racine=Tkinter.Tk() racine.geometry("400x300")
division=Tkinter.PanedWindow(orient=Tkinter.VERTICAL)
division.pack(expand="yes",fill="both")
panneau1=Tkinter.Label(division,text="Panneau Un") division.add(panneau1)
panneau2=Tkinter.Label(division,text="Panneau Deux") division.add(panneau2)
panneau3=Tkinter.Label(division,text="Panneau Trois")
division.add(panneau3) racine.mainloop()
On adapte cette fonction dans l'autre direction avec les paramètres suivants: orient=Tkinter.HORIZONTAL.
Il est possible de créer des subdivisions dans un des panneaux. Dans l'exemple suivant, c'est le panneau 'bas' qui
devient l'objet à diviser par PanedWindows: c'est donc à lui que les sous-panneaux 'gauche' et 'droite' doivent se
référer.
import Tkinter racine=Tkinter.Tk() racine.geometry("400x300")
division=Tkinter.PanedWindow(orient=Tkinter.VERTICAL)
division.pack(expand="yes",fill="both")
haut=Tkinter.Label(division,text="Panneau du haut") division.add(haut)
milieu=Tkinter.Label(division,text="Panneau du milieu")
division.add(milieu) bas=Tkinter.PanedWindow(orient=Tkinter.HORIZONTAL) #
nouvelle division bas.pack(expand="yes",fill="both")
gauche=Tkinter.Label(bas,text="Panneau bas-gauche") bas.add(gauche)
droit=Tkinter.Label(bas,text="Panneau bas-droit") bas.add(droit)
division.add(bas) # on acheve la déclaration du panneau bas
racine.mainloop()
5. Listes et menus
5.1 'Listbox'
import Tkinter racine=Tkinter.Tk()import Tkinter
liste=Tkinter.Listbox(racine,width=10) liste.pack()
texte=Tkinter.Text(racine,width=10) texte.pack() for element in ["Monthy",
"Python", "Flying", "Circus"]:
liste.insert(Tkinter.END, element) def
clic(inutile):
texte.insert(Tkinter.END,liste.get(liste.curselection())+"\n")
liste.bind('<Double-1>', clic) racine.mainloop()
'inutile' est une variable nécessaire mais qu'on n'utilise pas.
liste=Tkinter.Listbox(selectmode=Tkinter.EXTENDED) permet un mode de sélection multiple avec Ctrl-Clic,
Maj-Clic... MULTIPLE permet une sélection multiple par ajout de simple clic.
Il est possible de remplacer le double-clic par un bouton.
#! /usr/bin/python import Tkinter racine=Tkinter.Tk()
liste=Tkinter.Listbox(racine,width=10) liste.pack()
bouton=Tkinter.Button(racine,text='Confirmer') bouton.pack()
texte=Tkinter.Text(racine,width=10) texte.pack() for element in ["Monthy",
"Python", "Flying", "Circus"]:
liste.insert(Tkinter.END, element) def
clic(inutile):
texte.insert(Tkinter.END,liste.get(liste.curselection())+"\n")
bouton.bind('<Button-1>', clic) racine.mainloop()
5.2 'Scrollbar'
'Scrollbar' permet de placer un ascenseur, afin de manipuler plus facilement une 'Listbox'. L'exemple ci-dessous
montre qu'il est possible de prévoir un défilement vertical à partir d'un ascenseur horizontal.
import Tkinter racine = Tkinter.Tk() ascenseur=
Tkinter.Scrollbar(racine,orient=Tkinter.HORIZONTAL)
ascenseur.pack(side=Tkinter.TOP,fill=Tkinter.X) liste=
Tkinter.Listbox(racine, yscrollcommand=ascenseur.set) for i in
range(0,128):
liste.insert(Tkinter.END, str(i))
liste.pack(fill=Tkinter.Y) ascenseur.config(command=liste.yview)
racine.mainloop()
orient=Tkinter.HORIZONTAL pour un ascenseur horizontal (vertical par défaut), même si la commande a une
action verticale: 'yview'
fill=Tkinter.X met de l'espace entre les deux flèches de l'ascenseur horizontal
side=Tkinter.LEFT aurait placé l'ascenseur à gauche
5.3 'Menu'
Voici un exemple commenté d'un système de menu fonctionnel comportant des cascades (sous-menus). Pour la
fonction Menu, deux méthodes sont nécessaires: add_cascade pour ajouter un menu ou un sous-menu, et
add_command pour décider de la commande associée au clic. Les actions sont ici limitées à l'affichage d'un
texte.
import Tkinter racine=Tkinter.Tk() texte=Tkinter.Text(racine) # prevoit
une place pour l'affichage des textes texte.pack() def ecran(var): #
fonction servant a l'affichage des textes:
texte.insert(Tkinter.END,var)
sysdemenu = Tkinter.Menu(racine) # Creation du systeme de menu (variable
explicite sysdemenu): menu1 = Tkinter.Menu(sysdemenu) # Creation du
premier menu: sysdemenu.add_cascade(label="Menu 1", menu=menu1) # addition
des deux items pour le premier menu et leur commande associee
menu1.add_command(label="Cr\xe9dit", command=lambda: ecran('Cr\xe9dit:
www.jchr.be\n')) menu1.add_command(label="Quitter", command=racine.quit)
menu2 = Tkinter.Menu(sysdemenu) # Creation du second menu
sysdemenu.add_cascade(label="Menu 2", menu=menu2) # addition du premier
item pour le second menu et leur sous-items associes item1 =
Tkinter.Menu(menu2) menu2.add_cascade(label="Item 1", menu=item1) #
addition des sous-items du premier item du second menu et leur commande
associee item1.add_command(label="Action 1", command=lambda: ecran('Item 1
/ Action 1\n')) item1.add_command(label="Action 2", command=lambda:
ecran('Item 1 / Action 2\n')) item2 = Tkinter.Menu(menu2) # addition du
second item pour le second menu et leur sous-items associes
menu2.add_cascade(label="Item 2", menu=item2) # addition des sous-items du
second item du second menu et leur commande associee
item2.add_command(label="Action 1", command=lambda: ecran('Item 2 / Action
1\n')) item2.add_command(label="Action 2", command=lambda: ecran('Item 2 /
Action 2\n')) item2.add_command(label="Action 3", command=lambda:
ecran('Item 2 / Action 3\n')) racine.config(menu=sysdemenu)
racine.mainloop()
Chaque menu commence par une ligne discontinue. Un clic transfère le menu dans une fenêtre indépendante. On
peut empêcher cela en ajoutant le paramètre tearoff=0 dans la fonction 'Menu'
7. Styles
7.1 Couleurs
Pour les paramètres foreground, fg, background, bg, fill, outline
On utilise la forme "#RRGGBB" où les lettres représentent le rouge, le vert et le bleu en chiffres hexadécimaux
(de '0' à '9' puis de 'a' à 'f'). Il existe aussi des noms parmi lesquels:
black, dark-gray, gray, light-gray, white
cyan, blue, violet, magenta, red, yellow, green
gold, pink, orange
7.2 Alignements
Pour side (boutons) ou justify (textes)
Tkinter.LEFT, Tkinter.RIGHT, Tkinter.TOP, Tkinter.BOTTOM
Pour anchor (images):
Tkinter.N, Tkinter.S, Tkinter.E, Tkinter.W, Tkinter.NE, Tkinter.SE, Tkinter.NW, Tkinter.SW, Tkinter.CENTER
7.3 Reliefs
relief peut prendre les valeurs Tkinter.RAISED, FLAT, SUNKEN, GROOVE et RIDGE
borderwidth, bd permet de préciser la grosseur des traits
7.4 Fontes
Valable pour 'Label', 'Text' et 'create_text', il y a plusieurs manières d'imposer une fonte, une hauteur et une
décoration:
font =("Helvetica", "16", "bold italic overstrike underline")
font=("-*-lucidatypewriter-medium-r-*-*-*-200-*-*-*-*-*-*")
Une autre manière est d'utiliser le module tkFont.
8. Modules associés
Les quatre librairies qui suivent permettent de définir l'option suivante:
parent= pour désigner la fenêtre parente lorsque la boîte est refermée
8.1 Boîtes à message
import tkMessageBox as Msg importe les fonctions de boîte à messages, à préfixer de Msg.
Retournent 'ok':
Msg.showinfo(title="",message="")
Msg.showwarning(title="",message="")
Msg.showerror(title="",message="")
Retournent 'yes' ou 'no':
Msg.askquestion(title="",message="")
Retournent True ou False:
Msg.askokcancel(title="",message="")
Msg.askyesno(title="",message="")
Msg.askretrycancel(title="",message="")
Il est possible de définir les choix par default=
Msg.ABORT, Msg.RETRY, Msg.IGNORE, Msg.OK, Msg.CANCEL, Msg.YES, Msg.NO
8.2 Boîtes de saisie
import tkSimpleDialog as Saisie
chaine= Saisie.askstring(title="", prompt="")
entier= Saisie.askinteger(title="", prompt="")
decimal= Saisie.askfloat(title="", prompt="")
On peut ajouter quelques options:
initialvalue= valeur de départ (chaîne, entier ou décimal)
minvalue= valeur minimale
maxvalue= valeur maximale
8.3 Sélectionneur de fichier
import tkFileDialog as Selector
descr=Selector.askopenfilename()
descr=Selector.asksaveasfilename()
(voir ici pour la manipulation du descripteur de fichier). Options:
initialdir="" répertoire
initialfile="" fichier (ignoré pour 'open')
defaultextension="" permet de définir une extension
filetypes="dsc01*" permet d'appliquer un filtre, "*" par défaut.
8.4 Choisir une couleur
((rouge,vert,bleu),couleur)=tkColorChooser.askcolor() fait apparaître un sélectionneur de couleur. Le sous-nuple définit trois variables (de 0 à 255) pour les couleurs fondamentales, couleur contiendra la couleur au format
#RRVVBB
Il est possible de recueillir la couleur en une seule variable:
#! /usr/bin/python import tkColorChooser couleur=tkColorChooser.askcolor()
print couleur[0][0] # est la quantite de rouge print couleur[0][1] # est la
quantite de vert print couleur[0][2] # est la quantite de bleu print
couleur[1]
# est la couleur sous forme #RRVVBB
askcolor() admet comme paramètres initialcolor=(rouge,vert,bleu) (trois nombres <256) pour une couleur
préalablement définie et title="" pour définir un titre de boîte.
9. Documentation
9.1 Documentation dans le logiciel python
Dans le mode interactif (obtenu en saisissant python dans une console):
>>> print dir() liste les modules chargés
>>> print Tkinter.__file__ renvoie la localisation de Tkinter sur le système
>>> print dir(Tkinter) liste les instructions du module Tkinter
>>> print Tkinter.fct.__doc__ documente l'instruction précisée de Tkinter
La commande help informe sur une fonction d'un module importé:
>>> import Tkinter
>>> help(Tkinter.Button)
9.2 Documentation sur votre système GNU+Linux
Si python est installé, saisir man python dans une console renseigne sur les différentes manières de lancer
python.
Le script /usr/bin/pydoc permet la consultation d'information de fonctions, modules, mots-clés:
pydoc -g lance une interface graphique pour une navigation dans le système d'aide
/usr/share/doc/python (adresse pouvant varier selon la distribution) contient quelques fichiers d'aide
9.3 Documentation sur Internet (anglais)



http://docs.python.org/lib/module-Tkinter.html
http://www.pythonware.com/library/
http://effbot.org/tkinterbook/
9.4 Documentation sur papier


John E. Grayson, Python and Tkinter Programming, Manning Publications
Alex Martelli & David Ascher, eds.: "python cookbook", o'reilly, 2002 (anglais) comporte peu de
choses sur le module Tkinter.
Téléchargement