Ceci est une ancienne révision du document !
Créer des interfaces graphiques avec Tkinter
Présentation
Tkinter est une librairie basique mais très simple d'utilisation pour construire rapidement des interfaces graphiques avec Python.
Le style de widgets n'est pas très esthétique (question de goût) mais ça reste tout de même une bonne base pour commencer dans le développement d'interface graphique (GUI).
Installation
- python-imaging-tk pour la gestion des images sous tkinter
- python3-tk pour la version 3.x de python.
Ceci peut se résumer avec l'outil apt-get en saisissant dans un terminal les commandes suivantes:
sudo apt-get install python-tk sudo apt-get install python-imaging-tk sudo apt-get install python3-tk
Etude d'un programme simple
Pour commencer, regardez et essayer de comprendre la structure du code :
#!/usr/bin/env python # -*- coding: Latin-1 -*- # # Programme Tkinter.py # from Tkinter import * #Pour python3.x Tkinter devient tkinter class ApplicationBasic(): '''Application principale''' def __init__(self): '''constructeur''' self.fen = Tk() self.fen.title('Tkinter') self.bou_action = Button(self.fen) self.bou_action.config(text='Action', command=self.action) self.bou_action.pack() self.bou_quitter = Button(self.fen) self.bou_quitter.config(text='Quitter', command=self.fen.destroy) self.bou_quitter.pack() self.fen.mainloop() def action(self): '''Action sur un bouton''' self.lab = Label(self.fen) self.lab.config(text='Bravo!!!') self.lab.pack() if __name__ == '__main__': app = ApplicationBasic()
chaque partie correspond à :
- importation de la librairie :
from Tkinter import *
- la création d'une classe :
class ApplicationBasic():
- la création d'une méthode constructrice :
def __init__(self):
- instancier une fenêtre Tk() :
self.fen = Tk()
- définition du titre de cette fenêtre :
self.fen.title('Tkinter')
- création d'un simple bouton action :
self.bou_quitter = Button(self.fen)
à moins que ce ne soit
self.bou_action = Button(self.fen)
pour le bouton action ???
- configuration de ce bouton :
self.bou_action.config(text='Action', command=self.action)
- mise en place de celui-ci dans la fenêtre avec une méthode de placement :
self.bou_action.pack()
- définition de la fonction qui sera connecté au bouton Action :
ef action(self) : '''Action sur un bouton''' self.lab = Label(self.fen) self.lab.config(text='Bravo!!!') self.lab.pack()
- même travail pour créer un bouton quitter. Ici vous constaterez qu'il n'est pas nécessaire de créer une fonction dédiée à ce bouton, la commande associée faisant le nécessaire :
self.bou_quitter = Button(self.fen) self.bou_quitter.config(text='Quitter', command=self.fen.destroy) self.bou_quitter.pack()
- lancement du gestionnaire d'événements :
self.fen.mainloop()
- assignation de la classe à une variable :
app = ApplicationBasic()
Enregistrer votre fichier source avec une extension .py puis lancez-le depuis un terminal en saisissant la commande suivante:
python 'fichier.py'
Configurer correctement sa fenêtre
Nous allons voir dans cette section comment bien configurer sa fenêtre selon le but recherché. Nous prendrons comme référence les variables du programme précédent. Voici les principales configurations les plus utilisées :
Titre
La configuration du titre de la fenêtre s'effectue trés simplement :
self.fen.title('Votre Titre')
Dimensions
Pour configurer la taille :
self.fen.geometry((400x400))
Le code peut varier selon la logique du développeur, nous pourions trés bien écrire :
self.taille = (400,400) self.fen.geometry(self.taille)
ou encore pour un petit exemple :
self.fenwidth = 400 self.fenheight = 400 self.fen.geometry((self.fenwidth,self.fenheight))
Noter que la configuration des dimensions se fait selon le shéma: 'largeur' x 'hauteur'.
Placement sur l'écran
Imaginer maintenant vouloir placer une fenêtre de (400x400) centré sur votre écran. Pour ma part je créerais une fonction gérant cela :
self.screenwidth = self.fen.winfo_screenwidth() #Récupération de la largeur de l'écran self.screenheight = self.fen.winfo_screenheight() #Récupération de la hauteur de l'écran def geometry_fen(self) : '''Cette fonction est utilisée pour mettre à jour les éléments graphiques et créer une géométrie pour la fenêtre.''' self.fen.update_idletasks() #Recalcul des propriétés de la fenêtre en prenant en compte les widgets placés. self.fenwidth = 400 #Définition de la largeur de la fenêtre. self.fenheight = 400 #Définition de la hauteur de la fenêtre. x = (self.screenwidth/2) - (self.fenwidth/2) #Division par 2 de la largeur de l'écran moins la largeur de la fenêtre par 2. y = (self.screenheight/2) - (self.fenheight/2) #Division par 2 de la hauteur de l'écran moins la hauteur de la fenêtre par2. self.fen.geometry('%dx%d+%d+%d' % (self.fenwidth, self.fenheight, x, y)) #Définition de la géométrie de la fenêtre.
Pour appliquer la géométrie, il vous suffira de lancer cette fonction avant de lancer le gestionnaire d'événements.
Redimmensionnement
Le redimensionnement de la fenêtre, par défaut est vrai autant pour x et y. Cela veut dire que l'utilisateur peut modifier autant qu'il le souhaite la largeur comme la hauteur de la fenêtre.
Comment interdire le redimmensionnement de la fenêtre ?
self.fen.resizable(False,False) #Toujours suivant le même schéma : largeur, hauteur.
Est-il possible d'interdire de modifier seulement la hauteur ou la largeur ?
self.fen.resizable(True,False) #Pour autoriser seulement le changement en x. self.fen.resizable(False,True) #Pour autoriser seulement le changement en y.
Style de fenêtre
Il es tout à fait possible de créer une fenêtre sans bordures. Cette configuration sera parfaitement adapter pour un SplashScreen par exemple. Regardons un exemple de code:
#!/usr/bin/env python # -*- coding: Latin-1 -*- # # tkinterEditorSplashScreen.py # # # [[[ Splash Screen de tkinter Editor]]] # # from Tkinter import * import os class SplashScreen(): '''Splash Screen tkinterEditor''' def __init__(self): '''Constructeur''' self.fen = Tk() self.fen.resizable(False,False) self.fen.overrideredirect(1) self.screenwidth = self.fen.winfo_screenwidth() self.screenheight = self.fen.winfo_screenheight() self.surface = Canvas(self.fen, bg='light blue', bd=6, relief='sunken') self.surface.pack(fill=BOTH, expand=1) self.surface.create_line(0,0,600,400, fill='red', width=4) self.surface.create_line(0,10,600,400, fill='yellow', width=4) self.surface.create_line(0,20,600,400, fill='red', width=4) self.surface.create_line(0,30,600,400, fill='yellow', width=4) self.surface.create_line(0,40,600,400, fill='red', width=4) self.surface.create_line(0,50,600,400, fill='yellow', width=4) self.surface.create_line(0,100,600,400, fill='red', width=4) self.surface.create_line(0,110,600,400, fill='yellow', width=4) self.surface.create_line(0,120,600,400, fill='red', width=4) self.surface.create_line(0,130,600,400, fill='yellow', width=4) self.surface.create_line(0,140,600,400, fill='red', width=4) self.surface.create_line(0,150,600,400, fill='yellow', width=4) self.surface.create_line(0,200,600,400, fill='red', width=4) self.surface.create_line(0,210,600,400, fill='yellow', width=4) self.surface.create_line(0,220,600,400, fill='red', width=4) self.surface.create_line(0,230,600,400, fill='yellow', width=4) self.surface.create_line(0,240,600,400, fill='red', width=4) self.surface.create_line(0,250,600,400, fill='yellow', width=4) self.surface.create_line(0,300,600,400, fill='red', width=4) self.surface.create_line(0,310,600,400, fill='yellow', width=4) self.surface.create_line(0,320,600,400, fill='red', width=4) self.surface.create_line(10,0,600,400, fill='yellow', width=4) self.surface.create_line(20,0,600,400, fill='red', width=4) self.surface.create_line(30,0,600,400, fill='yellow', width=4) self.surface.create_line(40,0,600,400, fill='red', width=4) self.surface.create_line(50,0,600,400, fill='yellow', width=4) self.surface.create_line(100,0,600,400, fill='red', width=4) self.surface.create_line(110,0,600,400, fill='yellow', width=4) self.surface.create_line(120,0,600,400, fill='red', width=4) self.surface.create_line(130,0,600,400, fill='yellow', width=4) self.surface.create_line(140,0,600,400, fill='red', width=4) self.surface.create_line(150,0,600,400, fill='yellow', width=4) self.surface.create_line(200,0,600,400, fill='red', width=4) self.surface.create_line(210,0,600,400, fill='yellow', width=4) self.surface.create_line(220,0,600,400, fill='red', width=4) self.surface.create_line(230,0,600,400, fill='yellow', width=4) self.surface.create_line(240,0,600,400, fill='red', width=4) self.surface.create_line(250,0,600,400, fill='yellow', width=4) self.surface.create_line(300,0,600,400, fill='red', width=4) self.surface.create_line(310,0,600,400, fill='yellow', width=4) self.surface.create_line(320,0,600,400, fill='red', width=4) self.surface.create_line(330,0,600,400, fill='yellow', width=4) self.surface.create_line(340,0,600,400, fill='red', width=4) self.surface.create_line(350,0,600,400, fill='yellow', width=4) self.surface.create_line(400,0,600,400, fill='red', width=4) self.surface.create_line(410,0,600,400, fill='yellow', width=4) self.surface.create_line(420,0,600,400, fill='red', width=4) self.surface.create_line(430,0,600,400, fill='yellow', width=4) self.surface.create_line(440,0,600,400, fill='red', width=4) self.surface.create_line(450,0,600,400, fill='yellow', width=4) self.surface.create_line(500,0,600,400, fill='yellow', width=4) self.surface.create_oval(500,300,700,500, fill='yellow') self.titre = self.surface.create_text(300,20, anchor=N, text='Tkinter Editor', font='Times 40 bold italic', fill='blue') self.version = self.surface.create_text(360,80, anchor=NW, text='version 0.1', font='Times 15 bold italic', fill='blue') self.versionSplash = self.surface.create_text(10,390, anchor=SW, text='SplashScreen version 0.1', fill='red') def run(self): '''Lancement du Splash Screen''' self.fen.after(20000, self.start_tkinterEditor) self.geometry_fen() self.fen.mainloop() def start_tkinterEditor(self): '''Lancement de l'editeur Tk()''' self.fen.destroy() os.system('python tkinterEditor.py') def geometry_fen(self): '''Cette fonction est utilisé pour mettre à jour les éléments graphiques et créer une géométrie pour la fenêtre.''' self.fen.update_idletasks() self.fenwidth = 600 self.fenheight = 400 x = (self.screenwidth/2) - (self.fenwidth/2) y = (self.screenheight/2) - (self.fenheight/2) self.fen.geometry('%dx%d+%d+%d' % (self.fenwidth, self.fenheight, x, y)) if __name__ == '__main__': splashscreen = SplashScreen() splashscreen.run()
Et voilà le résultat:
Si vous avez bien observé le code, vous aurez remarqué cette ligne:
self.fen.overrideredirect(1)
C'est cette ligne qui indique que la fenêtre ne possédera pas de bordures. Un petit conseil concernant cette ligne de code, dans mon cas j'ai créer un SplashScreen qui reste (n) secondes à l'écran puis disparaît donc pas de problème. Dans le cas ou vous voudriez créer votre programme sans bordures, veuillez à toujours mettre un bouton quitter (de sortie) dans votre programme.
Les 4 widgets de base
Label
Le Label est utilisé pour afficher du texte dans la fenêtre.
Button
Un simple bouton cliquable.
Canvas
Le widget Canvas est le plus intéressant de tous les widgets présents dans la librairie. Pourquoi? Tout simplement parce que vous pouvez pousser vos interfaces graphiques au maximum autant dans le style que dans les fonctionnalités…. Pour une construction simple et rapide d'interface en Tk(), vous utiliserez la plupart du temps les méthodes de placement (pack(), grid(), place() ), nous expliquerons ces méthodes de placement un peu plus tard. Vous pourrez vous apercevoir que ces trois méthodes sont limitées et particulièrement linéaires.
Un peu de géométrie
Dessiner
Positionner des éléments
Déplacements d'éléments présents dans la Canvas
Entry
Zone de récupération de saisies utilisateur.
Les autres widgets
En construction
La configuration des widgets
Chaque widgets et configurable dans la limite du raisonnable . Nous allons voir dans cette partie comment configurer vos widgets pour s'approcher au maximum de ce que vous recherché.
Les couleurs
En construction
La police
En construction
Les dimensions
En construction
Reliefs et bordures
Pour la configuration des reliefs, vous utiliserez une variable de configuration nommé relief. Il existe actuellement 5 reliefs diffèrents les voici:
from Tkinter import * class ButtonReliefs(): '''5 reliefs de boutons''' def __init__(self): '''Constructeur''' self.fen = Tk() self.fen.title('les reliefs') self.fen.resizable(False,False) #Création self.lab_reliefs = Label(self.fen, width=50) self.bou_flat = Button(self.fen) self.bou_raised = Button(self.fen) self.bou_sunken = Button(self.fen) self.bou_groove = Button(self.fen) self.bou_ridge = Button(self.fen) #Configuration self.lab_reliefs.config(text='Reliefs:') self.bou_flat.config(text='FLAT', relief='flat') self.bou_raised.config(text='RAISED', relief='raised') self.bou_sunken.config(text='SUNKEN', relief='sunken') self.bou_groove.config(text='GROOVE', relief='groove') self.bou_ridge.config(text='RIDGE', relief='ridge') #placement self.lab_reliefs.pack() self.bou_flat.pack() self.bou_raised.pack() self.bou_sunken.pack() self.bou_groove.pack() self.bou_ridge.pack() self.fen.mainloop() if __name__ == '__main__': app = ButtonReliefs()
En image:
Autre
En construction
Relation Fonctions/Widgets
En construction
Les diffèrentes méthodes de placements
Il existe trois méthodes de placements dans la librairie Tkinter. L'utilisation très simpliste de ces méthodes vous ferrons gagner beaucoup de temps lors de vos codages.
Pack()
En construction
Grid()
En construction
Place()
En construction
Les évènements
Nous allons maintenant étudier les évènements, qui nous serviront à intercepter les actions utilisateur pour les traiter par le biais de fonctions. Tout programme possède un gestionnaire d'évènements, dans notre cas le démarrage de celui-ci correspond à la ligne
self.fen.mainloop()
du programme ci-dessus.
Souris
En construction
Clavier
En construction
Autres
En construction
Le Canvas, un widget intéressant
En construction
Un peu de multimédia
En construction
Gérer des images
En construction
Gérer de la musique
En construction
Qu'avons nous appris?
En construction
Exemple de programmes
PyQuizzz version 0.1 -- GUI - Tkinter (en cours de construction)
L'interface
En construction
Le code
En construction
Pour aller plus loin
En construction
Liens
Contributeurs:Boileau jonathan – Mail: boileau_jonathan@hotmail.fr