Programmation d’interfaces graphiques avec tkinter
Les fondamentaux
L’une des bibliothèques les plus populaires en Python pour créer des interfaces graphiques s’appelle tkinter. Cette bibliothèque provient d’un langage de programmation appelé Tcl, langage de programmation qui fut très populaire et apprécié pendant les années 2000. Ainsi, la bibliothèque tkinter est idéale dans le contexte du Raspberry Pi pour concevoir rapidement des interfaces graphiques dont la consommation en ressources est faible. Pour preuve, l’éditeur de code IDLE, présenté dans le chapitre Raspberry Pi 4, premier contact, est programmé avec tkinter. Pour familiariser rapidement le lecteur avec cette bibliothèque, les exemples sont présentés, comme d’habitude, du plus simple au plus complexe.
D’un point de vue théorique, une application tkinter se décompose en plusieurs couches, la couche de base représentant la fenêtre de l’application telle qu’elle apparaît à l’écran. La classe Tk constitue ce composant graphique qui doit être obligatoirement initialisé au début de chaque application utilisant la bibliothèque. Sur cette couche s’ajoutent et s’empilent ensuite d’autres composants graphiques permettant le plus souvent d’interagir avec la fenêtre, comme des boutons, des étiquettes...
Projet #1 : Hello world avec tkinter
Quoi de mieux que d’écrire le traditionnel exemple Hello world pour présenter les composants de la bibliothèque ? Pour le moment seulement, trois sont passés en revue : Label pour les champs texte, Button pour les boutons et Frame pour les cadres nécessitant un agencement particulier. Le code le plus basique qui illustre un Hello world avec tkinter se résume en ces quelques lignes (Chapitre_5/hello_1.py) :
1 #!/usr/bin/env python3
2 import tkinter
3 from tkinter import Label
4
5
6 def main():
7 fenetre = tkinter.Tk()
8 fenetre.geometry("300x150")
9 label = Label(fenetre, text="Hello world avec tkinter !")
10 label.pack()
11 fenetre.mainloop()
12
13
14 if __name__ == "__main__":
15 main()
Ici, le composant graphique Label crée une zone dans laquelle du texte peut être écrit. Notez la manière dont le widget est créé. En effet, le 1er argument doit correspondre à la fenêtre ou le cadre dans lequel le composant graphique est ajouté. Une fois l’élément créé, un gestionnaire de géométrie prend le relais et place les éléments dans la fenêtre. L’appel à la fonction pack() invoque le gestionnaire de géométrie Pack qui centre le champ texte au milieu de la fenêtre. À l’exécution du script, une fenêtre apparaît avec du texte :
La bibliothèque compte cependant deux autres gestionnaires de géométrie. Toujours en utilisant l’exemple Hello world, voici comment fonctionne le gestionnaire Place pour placer un élément à un endroit précis dans la fenêtre tkinter...
Projet #2 : une visionneuse d’images
Une visionneuse d’images sert essentiellement à visualiser des images. Le but de ce projet est donc de créer une fenêtre dans laquelle une image est affichée. Une application utile, en effet, car cette visionneuse affichera, peut-être, vos dernières photos de vacances !
Avant de commencer à travailler sur ce projet, il faut en premier lieu télécharger un composant nécessaire à l’écriture de cette application. En effet, la bibliothèque embarque par défaut le composant graphique PhotoImage pour afficher des images. Cependant, les formats d’images supportés par la bibliothèque sont limités car le composant ne peut afficher que les images aux formats GIF, PPM et PGM. Néanmoins, grâce à Pillow, une bibliothèque largement utilisée pour la manipulation d’images et abordée au chapitre Multimédia et audio sur le Raspberry Pi, les développeurs de tkinter ont pu étendre les capacités de PhotoImage afin d’afficher d’autres formats tels que JPEG ou PNG.
Pour refléter ce changement sur votre Raspberry Pi, il est donc nécessaire de télécharger le paquet python3-pil.imagetk. Voici la marche à suivre depuis un shell :
pi@raspberrypi:~ $ sudo su -
root@raspberrypi:~# apt-get install python3-pil.imagetk
L’outil apt-get vous demande alors de confirmer que ce paquet doit vraiment être installé, confirmation à laquelle il faudra répondre oui. Une fois le paquet installé, vérifiez que le module est effectivement disponible et présent sur le Raspberry Pi en tapant dans une console Python :
>>> from PIL import ImageTk
Si l’import s’exécute sans aucune erreur, cela veut dire que le module est correctement installé. Place au code !
Le code de la visionneuse est organisé au sein d’une classe, appelée PiVision. L’architecture de ce projet commence par les imports nécessaires puis la définition du constructeur de la classe (Chapitre_5/visionneuse_1.py) :
1 #!/usr/bin/env python3
2 import glob
3 import sys
4 import os
5 from tkinter import PhotoImage
6 from tkinter import Message
7 from tkinter import...
Projet #3 : un éditeur de texte
L’éditeur de texte, ou le meilleur compagnon du programmeur. La bibliothèque tkinter contient tous les ingrédients nécessaires pour écrire son propre éditeur en environ 150 lignes. Extrêmement léger pour une utilisation sur le Raspberry Pi. Évidemment, toutes les fonctionnalités d’un éditeur de texte classique ne sont pas couvertes, telles que la coloration syntaxique, la gestion des polices ou l’impression. Cependant l’essentiel est couvert et celui-ci se résume à : ouvrir un fichier (vierge ou existant), éditer son contenu et sauvegarder les changements.
Le nom donné à ce projet sera PiDiteur. Le projet commence par le traditionnel import des modules nécessaires (Chapitre_5/editeur_1.py) :
1 #!/usr/bin/env python3
2 import os
3 import sys
4 from tkinter import Frame, Menu, Label, TclError, X
5 from tkinter import END, SEL, SEL_LAST, SEL_FIRST, INSERT
6 from tkinter import YES, BOTH, BOTTOM, WORD, SUNKEN, TOP
7 from tkinter.filedialog import askopenfilename, asksaveasfilename
8 from tkinter.messagebox import askyesno, showinfo
9 from tkinter.scrolledtext import ScrolledText
10 from tkinter.simpledialog import askstring
En plus des traditionnels composants graphiques expliqués jusqu’à présent, la bibliothèque propose un panel de fenêtres et pop-ups préprogrammées pour éviter de réinventer la roue.
La classe principale porte le même nom que celui de l’éditeur et encapsule la logique de construction de l’éditeur de texte :
13 class PiDiteur(Frame):
14 def __init__(self, parent=None, nom_fichier=None):
15 Frame.__init__(self, parent)
16 self.pack(expand=YES, fill=BOTH)
17 self.fichier_courant = nom_fichier
18 self.nom_editeur = self.__class__.__name__
19 self.creer_composants()
20 self.gerer_evenements()
21 self.afficher_fichier(nom_fichier)
L’éditeur...
Conclusion
La bibliothèque tkinter est une candidate parfaite pour créer des interfaces graphiques légères destinées à être utilisées sur le Raspberry Pi. La plupart des projets abordés au cours de ce chapitre contiennent environ 100 lignes de code, ou plus, pour un résultat souvent étonnant (éditeur, diaporama…) !