Table des matières
Nous commencerons notre découverte de PyGTK avec le programme le plus simple possible. Ce programme (base.py) crée une fenêtre de 200x200 pixels et n'offre aucune possibilité de sortie, si ce n'est par le shell.
1 #!/usr/bin/env python 2 3 # exemple base.py 4 5 import pygtk 6 pygtk.require('2.0') 7 import gtk 8 9 class Base: 10 def __init__(self): 11 self.fenetre = gtk.Window(gtk.WINDOW_TOPLEVEL) 12 self.fenetre.show() 13 14 def boucle(self): 15 gtk.main() 16 17 print __name__ 18 if __name__ == "__main__": 19 base = Base() 20 base.boucle()
Vous pouvez exécuter le programme ci-dessus en tapant :
python base.py
Si base.py est rendu exécutable et qu'il se trouve dans votre PATH, il suffira de taper :
base.py
La ligne 1 invoquera alors Python pour exécuter le programme. Les lignes 5 et 6
font la distinction entre les différentes versions de PyGTK qui peuvent être installées
sur votre système. On précise que l'on veut utiliser la version 2.0 de PyGTK, ce qui
couvre toutes les versions dont le premier chiffre est 2. Ainsi, on empêche le programme
d'utiliser une version antérieure de PyGTK au cas où elle serait installée sur le système.
Les lignes 18 à 20 vérifient que la variable __name__
vaut bien
"__main__"
, ce qui indique que le programme est lancé directement à
partir de Python et non pas importé dans un interpréteur Python en cours de fonctionnement.
Si cette condition est vérifiée, le programme crée une nouvelle instance de la classe Base
et enregistre une référence à celle-ci dans la variable base. Puis il invoque la méthode
main
() pour démarrer la boucle de traitement des évènements GTK+.
Une fenêtre semblable à celle de la Figure 2.1, « Une simple fenêtre PyGTK » devrait apparaître à l'écran.
La première ligne permet au programme
base.py d'être invoqué à partir d'un shell Linux ou Unix,
pourvu que python figure dans votre PATH
. Cette
ligne doit être la première dans chacun des programmes exemples.
Les lignes 5 à 7 importent le module PyGTK 2 et initialise l'environnement GTK+.
Le module PyGTK définit les interfaces Python des fonctions GTK+ qui seront utilisées
dans le programme. Pour ceux qui connaissent déjà GTK+, l'initialisation comprend un
appel à la fonction gtk_init
(). Celle-ci règle plusieurs choses
pour nous, comme le format d'affichage et la table des couleurs par défaut, les
gestionnaires de signaux par défaut, etc. Elle vérifie également si un ou plusieurs des
paramètres suivants ont été passés à l'application via la ligne de commande :
Elle les retire alors de la liste des paramètres, et laisse tout ce qu'elle n'a pas reconnu être analysé ou ignoré par notre application. Ces paramètres sont standard, ils sont acceptés par toutes les applications GTK+.
Aux lignes 9 à 15, on définit une classe Python nommée
Base
, dans laquelle est définie une méthode d'initialisation
d'instance : __init__
(). Cette fonction crée une fenêtre
racine (ligne 11) et ordonne à GTK+ de l'afficher (ligne 12). La gtk.Window
est créée avec l'argument gtk.WINDOW_TOPLEVEL
, indiquant que l'on souhaite
que l'aspect et le positionnement de le fenêtre soient pris en charge par le gestionnaire de
fenêtres. Plutôt que de créer une fenêtre de 0x0 pixels, une fenêtre sans enfant a une taille
par défaut de 200x200 pixels de manière à pouvoir être manipulée facilement.
Aux lignes 14 et 15, on définit la méthode boucle
()
qui appelle la fonction main
() de PyGTK. Cette dernière
initialise la boucle principale du traitement des évènements de GTK, pour capter
les évènements de la souris, du clavier, même des fenêtres.
Les lignes 18 à 20 permettent au programme de démarrer automatiquement
s'il est appelé directement ou passé comme argument à l'interpréteur Python ;
dans ces deux cas, le nom du programme contenu dans la variable Python
__name__
sera la chaîne de caractères "__main__"
et le code des lignes 18-20 sera exécuté. Par contre, si le programme est
importé dans un interpréteur Python en cours de fonctionnement,
les lignes 18-20 seront ignorées.
À la ligne 19, on crée une instance de la classe
Base
nommée base. Ce qui a pour effet de créer et
d'afficher une gtk.Window
.
La ligne 20 invoque la méthode main
()
de la classe Base
, qui démarre la boucle du traitement
des évènements de GTK+. Une fois ce point atteint, GTK se met en attente d'évènements
en provenance de X (un clic sur un bouton, une touche enfoncée, etc.), de timeouts
ou de notifications d'entrées-sorties fichier. Dans notre exemple tout simple,
ils seront cependant ignorés.
Voici maintenant un programme avec un widget (un bouton). Il s'agit de la version PyGTK des classiques "Hello World" ( helloworld.py).
1 # !/usr/bin/env python 2 # coding: utf8 3 # exemple helloworld.py 4 5 import pygtk 6 pygtk.require('2.0') 7 import gtk 8 9 class SalutMonde: 10 11 # Ceci est une fonction de rappel. Les arguments sont ignorés dans 12 # cet exemple. Plus de précisions sur ces fonctions plus bas. 13 def salut(self, widget, donnees=None): 14 print "Salut tout le monde !" 15 16 def evnmt_delete(self, widget, evenement, donnees=None): 17 # Si on renvoie FALSE dans le gestionnaire du signal "evnmt_delete", 18 # GTK émettra le signal "destroy". Renvoyer TRUE signifie que l'on 19 # ne veut pas que la fenêtre soit détruite. 20 # Ceci peut être utile pour faire apparaître des fenêtres 21 # du type "Êtes vous sûr de vouloir quitter ?" 22 print "Évènement delete survenu." 23 24 # Changez FALSE par TRUE et la fenêtre principale ne 25 # sera pas détruite par un "delete_event" 26 return False 27 28 def destroy(self, widget, donnees=None): 29 print "Évènement destroy survenu." 30 gtk.main_quit() 31 32 def __init__(self): 33 # création d'une nouvelle fenêtre 34 self.fenetre = gtk.Window(gtk.WINDOW_TOPLEVEL) 35 36 # Quand la fenêtre reçoit le signal "delete_event" (donné par le 37 # gestionnaire de fenêtres, généralement par l'option "fermer" ou 38 # la croix de la barre de titre), on lui demande d'appeler la 39 # fonction evnmt_delete() définie plus haut. On lui passe l'argument 40 # NULL, qui est ignoré. 41 self.fenetre.connect("delete_event", self.evnmt_delete) 42 43 # Ici on connecte l'évènement "destroy" à un gestionnaire de signal. 44 # Cet évènement se produit lorsqu'on invoque gtk_widget_destroy() sur 45 # la fenêtre ou lorsque le gestionnaire du signal "delete" renvoie FALSE. 46 self.fenetre.connect("destroy", self.destroy) 47 48 # On fixe la largeur des bordures de la fenêtre. 49 self.fenetre.set_border_width(10) 50 51 # On crée un nouveau bouton avec l'étiquette "Salut tout le monde !". 52 self.bouton = gtk.Button("Salut tout le monde !") 53 54 # Lorsque le bouton reçoit le signal "clicked", il appelle la 55 # fonction salut() et lui passe None comme argument. La fonction 56 # salut() est définie plus haut. 57 self.bouton.connect("clicked", self.salut, None) 58 59 # Ceci entrainera la destruction de la fenêtre par l'appel de 60 # gtk_widget_destroy(fenetre) si l'on clique le bouton. Encore une fois, 61 # le signal "destroy" peut venir d'ici ou du gestionnaire de fenêtres. 62 self.bouton.connect_object("clicked", gtk.Widget.destroy, self.fenetre) 63 64 # On place le bouton dans la fenêtre (un conteneur GTK). 65 self.fenetre.add(self.bouton) 66 67 # La dernière étape consiste à afficher ce nouveau widget... 68 self.bouton.show() 69 70 # ...ainsi que la fenêtre 71 self.fenetre.show() 72 73 def boucle(self): 74 # Toutes les applications PyGTK doivent avoir un gtk.main(). Arrivé à ce point, 75 # le programme se met en attente d'un évènement (clic, appui d'une touche, etc.) 76 gtk.main() 77 78 # Si le programme est lancé directement ou passé en argument à l'interpréteur 79 # Python, ceci crée une instance de la classe SalutMonde et l'affiche 80 if __name__ == "__main__": 81 salut = SalutMonde() 82 salut.boucle()
La Figure 2.2, « Exemple "Salut tout le monde !" » montre la fenêtre obtenue avec helloworld.py .
Les variables et fonctions du module PyGTK portent toutes un nom de la forme
gtk.*
. Par exemple, le programme
helloworld.py fait appel à :
False gtk.main_quit() gtk.Window() gtk.Button()
... qui appartiennent au module PyGTK. Dans les prochaines sections, le préfixe gtk ne sera pas toujours précisé mais il sera à chaque fois sous-entendu. Les programmes d'exemple, évidemment l'utiliseront.