Vous êtes à peu près ici : Accueil  »   tutoriel PyGTK  »   PyGTK : sommaire

Chapitre 2. Premiers pas

Table des matières

2.1. "Hello World" en PyGTK
2.2. Le principe des signaux et des rappels
2.3. Évènements
2.4. Le "Hello World" pas à pas

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.

Figure 2.1. Une simple fenêtre PyGTK

Une simple fenêtre PyGTK.

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.

2.1. "Hello World" en PyGTK

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 .

Figure 2.2. Exemple "Salut tout le monde !"

Le programme exemple "Salut tout le monde !"

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.