Après avoir passé du temps à créer des interfaces graphiques à l'aide de TKinter et ceci très facilement, mais restant frustré par le mélange entre mon code et l'interface graphique, j'ai décidé de m'intéresser à un autre outil de création d'interfaces graphique. Après un moment d'exploration des différentes possibilités, je me suis décidé sur l'utilisation de PyGTK et Glade.

La raison de mon choix pour ces deux technologies est qu'elles sont multi-plateformes et que l'utilisation de Glade satisfait mon souhait de séparer le code de mon application de la partie interface graphique.

Si vous n'avait jamais entendu parlé de Glade avant, c'est un "Editeur d'Interface Graphique pour GTK+ et Gnome". Il génére des fichiers XML qui contiennent la description des interfaces graphique.

Le site web de PyGTK décrit ce qu'est PyGTK :

PyGTK fournit une interface Python pratique à utiliser pour la bibliothèque GTK+, prenant en charge tout les détails assomants tels que la gestion de la mémoire et les transtypages. Combiné avec PyORBit et gnome-python, elle peut être utilisé afin d'écrire des applications Gnome riches.

Bien, nous y voici, j'écris ceci sur mon systéme Debian fraîchement installé (NdT : et votre serviteur sur sa Ubuntu Edgy bien à jour ;). Si vous utilisez une distribution Linux Debian, ou un dérivé Debian (NdT : telle que Ubuntu, etc.), installer PyGTK et Glade est très simple :

apt-get install python-gtk2 python-glade2

Maintenant, il est temps de créer notre première interface graphique simple. Voici l'accueil de Glade lorsque vous le démarrez : glade_01.png

Pour créer notre fenêtre de base, il faut presser le bouton "Window" qui se trouve sur la palette d'outils de Glade. Nous pouvons alors modifier les propriétés de cette fenêtre depuis le formulaire "Properties" : glade_02.png

Nous appellerons notre fenêtre Mainwindows et nous lui donnerons le titre (title) "Hello World... Again!".

Si vous avez l'habitude d'utiliser un environnement de développement intégré, par exemple Visual Studio, alors l'utilisation de Glade pourra vous paraître un peu étrange les premiers temps. Tout spécialement parce que vous ne pourrez pas placer les contrôles n'importe comment sur la fenêtre, mais que vous devrez utiliser des containers de placement pour les aligner. C'est d'autant plus étrange (au moins pour moi) que ceci est la méthode la plus couramment rencontrée dans les outils de construction d'interfaces graphique, et que des applications comme Visual Studio sont plutôt l'exception.

Revenons à notre tutoriel. La première chose que nous allons ajouter est un texte pour dire à l'utilisateur de cliquer sur le bouton (bien sûr, on pourrait mettre ce texte dans le bouton même, mais c'est moins amusant de n'avoir qu'un seul widget). Comme GTK utilise des containers pour aligner les widgets, la première chose que nous devons faire est de d'ajouter un container. Nous placerons notre texte au dessus du bouton, alors utilisons une Vertical Box avec 2 rangées. Pour ajouter la Vertical Box, cliquez simplement sur celle-ci dans la palette Glade, et ensuite cliquez dans notre fenêtre MainWindow. Un dialogue vous demandera alors combien de rangées vous voulez, et dans notre cas, nous en voulons deux.

L'action suivante sera d'ajouter le texte en cliquant sur Label dans la palette Glade et ensuite en cliquant dans la première rangée du container Vertical Box que nous venons de créer. Nous conservons le nom par défaut (label1), mais nous changeons le texte pour : "Please click on the button!". Le changement du texte se fait par l'intermèdiaire du formulaire Properties, qui, vous l'aurez remarqué, affiche et permet de modifier les propriétés du widget qui est sélectionné.

Ensuite, nous ajoutons un bouton de la même manière que pour le Label, excepté que nous le déposons dans la seconde rangée. Nous appellerons ce bouton btnHelloWorld, et il aura le texte "Click me!"

Il faut maintenant configurer les options de notre projet. J'appellerais ce projet PyHelloWorld et le sauverais dans mon dossier projects/PyHelloWorld. N'oubliez pas de sauver le projet. glade_03.png

Vous pourrez constater que deux fichiers ont été créés dans le dossier PyHelloWorld. L'un est le fichier projet de Glade avec l'extension .gladep et l'autre est notre interface graphique dans un fichier XML, avec l'extension .glade.

Maintenant, nous allons avoir besoin d'un programme Python pour charger et afficher le fichier .glade. Pour cela, dans le même dossier, je créé un fichier nommé PyHelloWorld.py. directory01.png

La première chose à faire est d'importer toutes les bibliothèques nécessaire à notre projet :

#!/usr/bin/env python
import sys
try:
        import pygtk
        pygtk.require("2.0")
except:
        pass
try:
        import gtk
        import gtk.glade
except:
        sys.exit(1)

Ensuite, nous crééons notre classe principale, je vais l'appeler HellowWorldGTK. Nous utilison la méthode init pour charger le fichier glade :

class HellowWorldGTK:
        """This is an Hello World GTK application"""

        def __init__(self):
               
                #Set the Glade file
                self.gladefile = "pyhelloworld.glade" 
                self.wTree = gtk.glade.XML(self.gladefile)
               
                #Get the Main Window, and connect the "destroy" event
                self.window = self.wTree.get_widget("MainWindow")
                if (self.window):
                        self.window.connect("destroy", gtk.main_quit)

La première chose qui est faite (après la définition de la classe) c'est indiquer le fichier glade que nous allons utiliser et créer un objet gtk.glade.XML pour cela. Voici la description de l'objet, reprise des références de pyGTK2 :

Cet objet représente une `instance` de la description d'une interface XML. Quand un de ces objets est créé, le fichier XML est lu, et l'interface est créée. L'objet gtk.glade.XML fournit alors une passerelle pour accéder aux widgets de l'interface graphique par leur noms au sein de la description XML. L'objet gtk.glade.XML peut aussi être utilisé pour connecter des fonctions aux signaux. Libglade met à disposition une interface avec laquelle il est possible de connecter les signaux aux fonctions de manière automique, ceci en parcourant la table des symboles du programme.

Ce qui est fait lorsque nous instancions notre objet gtk.glade.XML, c'est créer et charger notre interface graphique.

L'étape suivante et de récupérer l'instance de notre fenêtre principale et de connecter l'événement "destroy" sur la fonction gtk.main_quit(). Ceci permettra de quitter notre application lorsque l'on fermera la fenêtre principale. Sans ceci, l'application continuerait de s'exécuter alors que la fenêtre principale sera fermé (évidemment, ce n'est pas ce que nous voulons).

C'est tout pour la classe HellowWorldGTK, la prochaine étape qui est nécessaire et de créer une instance de notre classe et de démarrer la boucle principale GTK:

if __name__ == "__main__":
        hwg = HellowWorldGTK()
        gtk.main()

On y est, c'est plutôt facile, si vous exécuter ce fichier, la fenêtre GTK apparaîtra et se contentera, pour toute action, de vous permettre de quitter proprement quand vous fermerez la fenêtre. gtkhelloworld.png

La prochaine étape est la connexion de l'événement de clic sur le bouton à une fonction. Pour cela, nous utiliserons à nouveau Glade.

Dans notre fenêtre, nous sélectionnons l'objet bouton puis, dans le formulaire des propriétés, nous choisissons l'onglet "Signals". C'est à cet endroit que l'on va ajouter un nouveau signal en cliquant sur le bouton (...) et en choisissant "clicked". Ceci va créer un gestionnaire nommé "on_btnHelloWorld_clicked". Nous pourrions changer son nom, mais sa valeur par défaut convient pour l'instant. glade_04.png

Nous en avons terminé avec Glade, maintenant, il nous reste à connecter cet événement à quelquechose dans notre code. Heureusement, c'est facilement réalisable par l'intermédiaire de la fonction gtk.glade.XML.signal_autoconnect

#Create our dictionay and connect it
dic = { "on_btnHelloWorld_clicked" : self.btnHelloWorld_clicked,
        "on_MainWindow_destroy" : gtk.main_quit }
self.wTree.signal_autoconnect(dic)

En simplifiant, le dictionnaire est créé en utilisant le nom de de l'événement, et la fonction qui est sera connecté. Vous pouvez voir que l'on connecte l'événement du clic sur le bouton à une nouvelle fonction, et que nous connectons l'événement "on_MainWindow_destroy" à la fonction gtk.main_quit() . Ceci remplace notre code précédent qui quittait le programme à la fermeture de la fenêtre.

Important : Si vous voulez utiliser cette version du dictionnaire d'événements, vous devrez utiliser Glade pour ajouter un événement destroy dans les signaux de la fenêtre.

Note : Comme certains d'entre vous pourrait passer à côté, j'ai ajouté une image qui rend l'opération plus évidente : glade_05.png glade_06.png

Il faut ensuite créer la fonction btnHelloWorld_clicked dans la classe HellowWorldGTK :

def btnHelloWorld_clicked(self, widget):
        print "Hello World!"

Simplissime! Maintenant, quand nous l'exécutons et que nous cliquons sur le bouton "Click Me!", nous voyons "Hello World!" s'écrire sur le ligne de commande.

Cette leçon est terminée, et pour finir, je dirais que j'aime vraiment tout ce qui se fait avec PyGTK et Glade. Voici le code source complet :

#!/usr/bin/env python

import sys
try:
        import pygtk
        pygtk.require("2.0")
except:
        pass
try:
        import gtk
        import gtk.glade
except:
        sys.exit(1)

class HellowWorldGTK:
        """This is an Hello World GTK application"""

        def __init__(self):
               
                #Set the Glade file
                self.gladefile = "pyhelloworld.glade" 
                self.wTree = gtk.glade.XML(self.gladefile)
               
                #Create our dictionay and connect it
                dic = { "on_btnHelloWorld_clicked" : self.btnHelloWorld_clicked,
                        "on_MainWindow_destroy" : gtk.main_quit }
                self.wTree.signal_autoconnect(dic)

        def btnHelloWorld_clicked(self, widget):
                print "Hello World!"


if __name__ == "__main__":
        hwg = HellowWorldGTK()
        gtk.main()

Liens utiles :

NdT : Je ne suis pas un traducteur professionnel, aussi je vous demande un peu d'indulgence :)