Beaucoup de personnes partent du principe que Python n’est qu’un langage de script et le cantonnent à l’automatisation des tâches. Grâce à des frameworks, on peut aussi s’en servir pour faire des clients lourds. Le module tkInter qui permet de faire des boîtes de dialogues assez facilement et a longtemps été utilisée par les ingénieurs systèmes pour développer des mini-applications et faciliter leur travail. Il existe des portages de GTK, Qt et wxWidgets pour Python qui permettent de faire de belles applications. Spyder, par exemple, est un IDE pour Python qui est écrit en Python avec du Qt. Dans cet article nous allons travailler avec wxPython qui est le portage de wxWidgets ; une bibliothèque que j’ai utilisée à de nombreuses reprises pour faire un démonstrateur ou pour faire des outils internes pour des clients.
wxPython ?
> Installation
La bibliothèque wxPython est disponible sur le site www.wxPython.org . Vous y trouverez toutes les informations utiles pour l’installation ainsi que la documentation en ligne.
Sous Windows et Mac, l’installation peut se faire via l’utilitaire pip grâce à la commande suivante :
pip install -U wxPython
Sous Windows, si vous utilisez Anaconda, vous pouvez utiliser l’outil de gestion de package fournit par cette distribution : Anaconda Navigator :
Suivant la façon dont est installé votre PC, il sera peut-être nécessaire d’exécuter Anaconda Navigator en mode Administrateur afin de permettre la mise à jour.
Pour Linux, compte-tenu des nombreuses distributions, l’installation peut s’avérer plus complexe :
pip install -U \
-f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-16.04 \
wxPython
Il faut alors bien choisir sa version en fonction de la distribution cible.
> Les extras ?
À chaque nouvelle version de wxPython, vous trouverez un lien pour accéder aux extras.
L’un des gros intérêts de
wxPython est l’application « wxPython-demo » présente dans ces
extras. Voici un aperçu de
l’application :
Cette application est écrite en
Python avec wxPython et permet de naviguer dans toutes les fonctionnalités de
la bibliothèque, de voir des exemples des contrôles graphiques et d’accéder au
code.
Cela permet de développer plus rapidement son application 😊 sans avoir besoin de lire complètement la documentation.
Extras contient aussi la documentation offline pour ceux qui travaillent souvent en déplacement sans avoir une connexion internet.
> Outils ?
Créer des interfaces utilisateurs
peut être compliqué et il existe des outils pour faciliter leur création. Pour
wxPython, vous pouvez utiliser wxFormBuilder ou wxGlade qui sont, tous deux,
gratuits et téléchargeable sur le net.
« HELLO WORLD »
Avant de se lancer dans
l’écriture d’une application plus complexe, nous allons commencer par créer une
application ‘boîte de dialogue’ qui affiche le message « Hello
World ». Puis nous y rajouterons un bouton ce qui nous permettra de
comprendre le positionnement des contrôles.
> Au commencement, l’application
Avant toute chose, il faut créer
une instance de wx.App qui fournira les fonctionnalités de gestion des
événements : sans cet instance, rien ne fonctionnera.
Pour l’instant, ce programme s’exécute mais n’affiche rien. La fonction OnInit de notre classe est appelée pour initialiser le GUI après le constructeur : elle doit retourner True pour que l’application puisse d’initialiser proprement.
> Créer une boîte de dialogue
Une fois l’application créée, il
faut afficher une fenêtre. Le type de fenêtre le plus simple que l’on puisse
utiliser est la boîte de dialogue wx.Dialog : nous allons créer une classe
qui en dérive.
‘parent’ désigne l’objet parent de la boîte de dialogue : la première fenêtre n’a pas de parent, on lui passe None. ‘title’ contient le nom qui sera affiché dans la barre de titre. ‘id’
est un identifiant unique qui désigne une fenêtre, cela permet d’aiguiller les
événements aux bons composants. Si on définit ‘id’ à -1, on demande à wxPython
de générer automatiquement un identifiant.
Pour permettre à l’application d’afficher la boîte de dialogue il faut modifier la fonction OnInit :
La première étape consiste à créer l’objet MyDialog et de
stocker l’instance dans ‘dlg’. Cela ne suffit pas à déclencher l’affichage, il
faut appeler la fonction ShowModal. Tant que la boîte n’est pas fermée, la
ligne après n’est pas exécuté : le ShowModal est une action bloquante. Une
fois la boîte fermée, il faut penser à supprimer les objets systèmes liés en
appelant la fonction Destroy.
Lorsque l’on exécute le programme on obtient :
> Et mon « Hello World »
Maintenant que ma boîte de dialogue s’affiche, il nous
faut rajouter un champ texte avec « Hello World » à l’intérieur. En
regardant dans l’application wxPython-demo, on trouve ceci :
wx.StaticText
est un contrôle qui nous permet d’afficher un texte non-modifiable. Il nous
faut ajouter un appel dans la fonction ‘__init__’ de MyDialog :
Ce qui nous permet d’obtenir :
> Rajoutons un bouton OK et un bouton Cancel
En
recherchant dans wxPython-demo le bon contrôle, nous trouverons wx.Button. Et
son utilisation est assez simple :
A l’affichage on obtient :
Tous les contrôles s’affichent au même endroit. Outre le
fait que l’interface est illisible, il est impossible d’appuyer sur les
boutons ☹.
> Positionnement des contrôles et gestion des événements
Pour positionner les contrôles les uns par rapports aux autres, wxPython propose les ‘sizer’ :
wx.Sizer : une classe de base
wx.BoxSizer :
c’est une
‘boîte’ qui permet de ranger les contrôles les uns après les autres soit
horizontalement :
soit verticalement :
wx.GridSizer : c’est une grille de contrôles
Mettons en œuvre les sizers :
‘self.Bind’
permet de rediriger les événements. Dans le cas des boutons, il y a 3
paramètres :
wx.EVT_BUTTON : l’identifiant de l’événement « appui sur un bouton »
la fonction qui doit recevoir l’événement
l’objet wx.Button dont on veut capter l’appui
Les handlers
d’événements OnOK et OnCancel servent à clore la boîte de dialogue. Pour se
faire il faut appeler la fonction self.EndModal en lui passant l’identifiant de
l’événement.
L’ajout de
contrôles dans les sizers se fait via la fonction ‘Add’ ; les paramètres
d’appel sont :
le contrôle à ajouter
‘proportion’ : un entier qui définit la proportion
‘flag’ : un masque d’options
‘border’ : l’épaisseur de la bordure
‘userData’ : une donnée utilisateur que l’on peut attacher
Le sizer le plus externe (celui qui contient tous les
contrôles) doit être ajouté à la fenêtre via la fonction ‘SetSizer’. Pour
ajuster la taille de chaque contrôle ainsi que celle de la fenêtre, nous appelons
la fonction ‘Fit’ sur le sizer le plus externe en lui passant en paramètre
l’objet de la fenêtre.
PASSONS AUX CHOSES SERIEUSES
Après cette mise en bouche avec
une application relativement simple, nous allons créer une application qui
permet de visualiser des images. Mon objectif est d’avoir un explorateur de
fichiers qui me permette de parcourir les fichiers du disque dur. Si je
double-clique sur un fichier « image » celle-ci s’affichera dans une
fenêtre et nous pouvons avoir plusieurs images ouvertes en même temps.
Il se trouve que wxPython propose
une classe wx.Image qui supporte plusieurs formats de fichiers bitmaps (BMP,
PNG, JPEG, GIF, ICO, TGA, TIFF, etc…). Par contre, pour afficher une image nous
utiliserons la classe wx.StaticBitmap qui est un contrôle.
Afin de se rapprocher d’un design
plus professionnel, nous ajouterons une barre d’outils ainsi qu’une barre de
menu. Cela nous permettra de comprendre leurs créations ainsi que la gestion
des événements associés.
CONCLUSION
wxPython est une bibliothèque qui vous permettra de développer rapidement des applications avec un look&feel professionnel. Elle est très intéressante tant pour faire un prototype/démonstrateur que pour faire une application interne. wxPython-demo est un formidable outil qui permet de rapidement trouver les contrôles qui correspondent à notre besoin ainsi que le code qui permet de les construire.