IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Apprendre à utiliser le module Python PyGTK 2.0


précédentsommairesuivant

II. Chapitre 2. Premiers 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.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
#!/usr/bin/env python

# exemple base.py

import pygtk
pygtk.require('2.0')
import gtk

class Base:
    def __init__(self):
        self.fenetre = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.fenetre.show()

    def boucle(self):
        gtk.main()

print __name__
if __name__ == "__main__":
    base = Base()
    base.boucle()

Vous pouvez exécuter le programme ci-dessus en tapant :

 
Sélectionnez
  python base.py

Si base.py est rendu exécutable et qu'il se trouve dans votre PATH, il suffira de taper :

 
Sélectionnez
  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 apparaitre à l'écran.

Image non disponible
Figure 2.1. 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 :

  • --gtk-module ;
  • --g-fatal-warnings ;
  • --gtk-debug ;
  • --gtk-no-debug ;
  • --gdk-debug ;
  • --gdk-no-debug ;
  • --display ;
  • --sync ;
  • --name ;
  • --class.

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 standards, 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 pixel, 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 chaine 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.

II-A. "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).

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
# !/usr/bin/env python
# coding: utf8
# exemple helloworld.py

import pygtk
pygtk.require('2.0')
import gtk

class SalutMonde:

    # Ceci est une fonction de rappel. Les arguments sont ignorés dans
    # cet exemple. Plus de précisions sur ces fonctions plus bas.
    def salut(self, widget, donnees=None):
        print "Salut tout le monde !"

    def evnmt_delete(self, widget, evenement, donnees=None):
        # Si on renvoie FALSE dans le gestionnaire du signal "evnmt_delete",
        # GTK émettra le signal "destroy". Renvoyer TRUE signifie que l'on
        # ne veut pas que la fenêtre soit détruite.
        # Ceci peut être utile pour faire apparaitre des fenêtres
        # du type "Êtes-vous sûr de vouloir quitter ?"
        print "Événement delete survenu."

        # Changez FALSE par TRUE et la fenêtre principale ne 
        # sera pas détruite par un "delete_event"
        return False

    def destroy(self, widget, donnees=None):
        print "Événement destroy survenu."
        gtk.main_quit()

    def __init__(self):
        # création d'une nouvelle fenêtre
        self.fenetre = gtk.Window(gtk.WINDOW_TOPLEVEL)

        # Quand la fenêtre reçoit le signal "delete_event" (donné par le
        # gestionnaire de fenêtres, généralement par l'option "fermer" ou
        # la croix de la barre de titre), on lui demande d'appeler la
        # fonction evnmt_delete() définie plus haut. On lui passe l'argument
        # NULL, qui est ignoré.
        self.fenetre.connect("delete_event", self.evnmt_delete)

        # Ici on connecte l'événement "destroy" à un gestionnaire de signal.
        # Cet événement se produit lorsqu'on invoque gtk_widget_destroy() sur
        # la fenêtre ou lorsque le gestionnaire du signal "delete" renvoie FALSE.
        self.fenetre.connect("destroy", self.destroy)

        # On fixe la largeur des bordures de la fenêtre.
        self.fenetre.set_border_width(10)

        # On crée un nouveau bouton avec l'étiquette "Salut tout le monde !".
        self.bouton = gtk.Button("Salut tout le monde !")

        # Lorsque le bouton reçoit le signal "clicked", il appelle la
        # fonction salut() et lui passe None comme argument. La fonction
        # salut() est définie plus haut.
        self.bouton.connect("clicked", self.salut, None)

        # Ceci entrainera la destruction de la fenêtre par l'appel de
        # gtk_widget_destroy(fenetre) si l'on clique le bouton. Encore une fois,
        # le signal "destroy" peut venir d'ici ou du gestionnaire de fenêtres.
        self.bouton.connect_object("clicked", gtk.Widget.destroy, self.fenetre)

        # On place le bouton dans la fenêtre (un conteneur GTK).
        self.fenetre.add(self.bouton)

        # La dernière étape consiste à afficher ce nouveau widget...
        self.bouton.show()

        # … ainsi que la fenêtre
        self.fenetre.show()

    def boucle(self):
        # Toutes les applications PyGTK doivent avoir un gtk.main(). Arrivé à ce point,
        # le programme se met en attente d'un événement (clic, appui d'une touche, etc.)
        gtk.main()

# Si le programme est lancé directement ou passé en argument à l'interpréteur 
# Python, ceci crée une instance de la classe SalutMonde et l'affiche
if __name__ == "__main__":
    salut = SalutMonde()
    salut.boucle()

La Figure 2.2, « Exemple "Salut tout le monde !" » montre la fenêtre obtenue avec helloworld.py.

Image non disponible
Figure 2.2. 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 à :

 
Sélectionnez
1.
2.
3.
4.
  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.

II-B. Le principe des signaux et des rappels

Nous n'entrerons pas dans le détail des différences entre les extensions du système de signaux de GLib 2.0 par rapport à celui de GTK 1.2. Les utilisateurs de PyGTK ne devraient pas remarquer de différence.

Avant de nous lancer dans une observation détaillée de helloworld.py, il nous faut expliquer les concepts de signal et de fonction de rappel. GTK est une boite à outils évènementielle, ce qui signifie qu'elle restera inactive dans gtk.main() jusqu'à ce qu'un événement survienne et que le relai soit passé à la fonction appropriée.

Ce passage de relais s'effectue par l'intermédiaire d'un « signal » (notez que ces signaux n'ont rien à voir avec les signaux système Unix, et ne sont pas implémentés en les utilisant, quoique la terminologie soit semblable). Lorsqu'un événement survient, comme un clic de souris, le signal correspondant est « émis » par le widget sur lequel on clique. C'est de cette façon que GTK réalise la plupart de son travail. Il y a des signaux dont tous les widgets héritent, comme "destroy", tandis que d'autres sont spécifiques à un widget, comme le "toggled" des boutons interrupteurs.

Pour qu'un bouton effectue une action, on définit un gestionnaire de signal qui sera chargé de capter ces signaux et d'appeler la fonction appropriée. On utilise alors une méthode de GtkWidget (de la classe GObject) comme ceci :

 
Sélectionnez
  gestionnaire_id = objet.connect(nom, fonction, donnees_fct)

où objet est l'instance de GtkWidget qui doit émettre le signal. Le premier argument, nom, est une chaine de caractères donnant le nom du signal que l'on veut intercepter. Le deuxième argument, fonction, est la fonction qui devra être appelée une fois le signal intercepté. Enfin, donnees_fct représente les données que l'on souhaite passer à cette fonction. La méthode renvoie un identifiant de gestionnaire gestionnaire_id, que l'on pourra utiliser pour déconnecter ou bloquer le gestionnaire.

La fonction indiquée en deuxième argument est une « fonction de rappel », et devrait généralement avoir la forme :

 
Sélectionnez
  def fct_rappel(widget, donnees_fct):

où le premier argument est un pointeur vers le widget qui a émis le signal, et le second (donnees_fct) un pointeur vers les données fournies en dernier argument à la méthode connect() ci-dessus.

Si la fonction de rappel est une méthode d'objet, elle aura généralement la forme suivante :

 
Sélectionnez
  def meth_rappel(self, widget, donnees_meth):

self est l'instance d'objet invoquant la méthode. C'est la forme utilisée dans le programme exemple helloworld.py.

La forme indiquée ci-dessus pour une déclaration de fonction de rappel n'est qu'un modèle général. Certains signaux spécifiques à un widget engendrent des paramètres d'appel différents.

Dans l'exemple helloworld.py, on trouve aussi un appel de la forme :

 
Sélectionnez
  handler_id = object.connect_object(name, func, slot_object)
  gestionnaire_id = objet.connect_object(nom, fonction, objet)

connect_object() est semblable à connect() à ceci près que la fonction de rappel ne nécessite qu'un seul argument et deux arguments pour la méthode :

 
Sélectionnez
  def fct_rappel(objet)
  def meth_rappel(self, objet)

objet est habituellement un widget. connect_object() permet aux méthodes de widget PyGTK qui ne prennent qu'un seul argument (self) d'être utilisées comme gestionnaires de signaux.

II-C. Événements

En plus du système de signaux décrit auparavant, un certain nombre d'événements reflètent le système évènementiel de X, des fonctions de rappel peuvent être associées à ceux-ci. En voici une liste :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
  event
  button_press_event
  button_release_event
  scroll_event
  motion_notify_event
  delete_event
  destroy_event
  expose_event
  key_press_event
  key_release_event
  enter_notify_event
  leave_notify_event
  configure_event
  focus_in_event
  focus_out_event
  map_event
  unmap_event
  property_notify_event
  selection_clear_event
  selection_request_event
  selection_notify_event
  proximity_in_event
  proximity_out_event
  visibility_notify_event
  client_event
  no_expose_event
  window_state_event

Pour connecter une fonction de rappel à l'un de ces événements, on utilise la méthode connect() décrite à la section précédente, en mentionnant l'un des noms d'événement ci-dessus comme paramètre nom. Les fonctions (ou méthodes) de rappel employées pour les événements sont légèrement différentes de celles utilisées pour les signaux :

 
Sélectionnez
1.
2.
3.
  def fct_rappel(widget, evenement, donnees_fct):

  def meth_rappel(self, widget, evenement, donnees_meth):

GdkEvent est un type d'objet Python dont l'attribut type indique lequel des événements ci-dessus est survenu. Les autres attributs de l'événement dépendent du type de celui-ci. Les valeurs pour les types peuvent être les suivantes :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
  NOTHING
  DELETE
  DESTROY
  EXPOSE
  MOTION_NOTIFY
  BUTTON_PRESS
  _2BUTTON_PRESS
  _3BUTTON_PRESS
  BUTTON_RELEASE
  KEY_PRESS
  KEY_RELEASE
  ENTER_NOTIFY
  LEAVE_NOTIFY
  FOCUS_CHANGE
  CONFIGURE
  MAP
  UNMAP
  PROPERTY_NOTIFY
  SELECTION_CLEAR
  SELECTION_REQUEST
  SELECTION_NOTIFY
  PROXIMITY_IN
  PROXIMITY_OUT
  DRAG_ENTER
  DRAG_LEAVE
  DRAG_MOTION
  DRAG_STATUS
  DROP_START
  DROP_FINISHED
  CLIENT_EVENT
  VISIBILITY_NOTIFY
  NO_EXPOSE
  SCROLL
  WINDOW_STATE
  SETTING

On accède à ces valeurs en préfixant le type d'événement avec gtk.gdk. Par exemple : gtk.gdk.DRAG_ENTER.

En résumé, pour connecter une fonction de rappel à un de ces événements, on peut procéder ainsi :

 
Sélectionnez
  bouton.connect("button_press_event", fct_rappel_bouton)

Ainsi, le fait de cliquer avec la souris lorsque le pointeur se trouve au-dessus du bouton invoque la fonction fct_rappel_bouton. On peut définir cette fonction comme ceci :

 
Sélectionnez
  def fct_rappel_bouton(widget, evenement, donnees):

La valeur renvoyée par cette fonction indique si l'événement doit être propagé par le système de gestion des événements de GTK+. Renvoyer True indique que l'événement a été traité et que sa diffusion s'arrête ici. En revanche, False laisse se poursuivre le processus normal de traitement de l'événement. Voir le Chapitre 20, Gestion avancée des signaux etChapitre 20. Gestion avancée des évènements et signauxévénements pour en apprendre plus sur ce processus de diffusion.

Les API de sélection et de glisser-déposer de GDK émettent également un certain nombre d'événements qui sont représentés dans GTK+ par des signaux. Voyez les sections 22.3.2 Les signaux du widget sourceLes signaux du widget origine et 22.3.4 Les signaux du widget destinationLes signaux du widget destination (pas encore traduites), si vous souhaitez en apprendre plus sur les signatures des fonctions de rappel pour les signaux suivants :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
  selection_received
  selection_get
  drag_begin_event
  drag_end_event
  drag_data_delete
  drag_motion
  drag_drop
  drag_data_get
  drag_data_received

II-D. Le "Hello World" pas à pas

Après ces explications plutôt théoriques, revenons à présent à notre programme helloworld.py pour un examen plus détaillé.

Les lignes 9 à 76 définissent la classe HelloWorld. Celle-ci contient toutes les fonctions de rappel en tant que méthodes d'objet, ainsi qu'un constructeur (méthode d'initialisation d'instance). Attardons-nous sur les fonctions de rappel.

Aux lignes 13 et 14, on trouve la définition de la méthode de rappel salut(), qui sera invoquée par un clic sur le bouton et affichera "Salut tout le monde !" dans la console. Nous ignorons les paramètres (l'instance, le widget émetteur et les données transmises) dans cet exemple, mais la plupart des fonctions de rappel les utilisent. Le paramètre donnees est défini avec une valeur par défaut valant None, car Pygtk ne transmettrait pas de valeur de données si elle n'est pas incluse dans l'appel à connect(). Dans un tel cas, une erreur se produirait, car la fonction de rappel, qui attend obligatoirement trois paramètres, n'en recevrait que deux. Définir None comme valeur par défaut permet à la fonction de rappel d'être invoquée avec deux ou trois paramètres sans déclencher d'erreur. Dans le cas de notre exemple, on aurait pu se passer du paramètre donnees puisque la méthode salut() sera toujours appelée avec seulement deux paramètres (jamais elle ne recevra de données utilisateur). Notre prochain programme utilisera cet argument donnees pour nous dire quel bouton a été cliqué.

 
Sélectionnez
  def salut(self, widget, donnees=None):
      print "Salut tout le monde !"

La fonction de rappel suivante (lignes 16 à 26) est un peu spéciale. L'événement "delete_event" se produit lorsque le gestionnaire de fenêtres envoie cet événement à l'application. On a le choix quant à ce que l'on souhaite faire de ces événements : les ignorer, faire quelque chose en réponse ou simplement quitter l'application.

La valeur que l'on fait renvoyer par cette fonction de rappel fait connaître notre décision à GTK+. Renvoyer TRUE lui indique que l'on ne veut pas que le signal "destroy" soit émis, laissant l'application se poursuivre. En renvoyant FALSE, en revanche, nous demandons à ce que le signal "destroy" soit émis, lequel appellera le gestionnaire de signal "destroy". Les commentaires ont été retirés pour plus de clarté :

 
Sélectionnez
1.
2.
3.
  def evnmt_delete(widget, evenement, donnees=None):
      print "Événement delete survenu."
      return False

La fonction de rappel destroy() des lignes 28-30, entraine la sortie du programme par un appel à gtk.main_quit(). Cette fonction ordonne à GTK+ de sortir de gtk.main() lorsque le contrôle lui est rendu.

 
Sélectionnez
1.
2.
3.
  def destroy(self, widget, donnees=None):
      print "Événement destroy survenu."
      gtk.main_quit()

Les lignes 32 à 71 définissent la méthode d'initialisation d'instance __init__() de HelloWorld, qui crée la fenêtre et les widgets utilisés par le programme.

À la ligne 34, on crée une nouvelle fenêtre. Cependant, celle-ci ne s'affichera que lorsque GTK+ en recevra l'ordre, vers la fin du programme. On enregistre une référence à cette fenêtre dans un attribut d'instance (self.fenetre) pour pouvoir y accéder plus tard.

 
Sélectionnez
    self.fenetre = gtk.Window(gtk.WINDOW_TOPLEVEL)

Les lignes 41 et 46 illustrent deux exemples de connexion d'un gestionnaire de signal à un objet, en l'occurrence à la fenêtre. Ici, on capte les signaux "delete_event" et "destroy". Le premier est émis lorsque l'on utilise le gestionnaire de fenêtres pour fermer la fenêtre, ou par un appel à la méthode destroy() de GtkWidget. Le second est émis lorsque dans le gestionnaire du "delete_event", on renvoie FALSE.

 
Sélectionnez
    self.fenetre.connect("delete_event", self.evnmt_delete)
    self.fenetre.connect("destroy", self.destroy)

La ligne 49 précise un attribut d'un objet conteneur, ici la fenêtre, pour lui donner un espace vide de 10 pixels de large le long de son périmètre intérieur, où aucun widget ne pourra être placé. D'autres fonctions similaires existent, nous nous y intéresserons dans le Chapitre 18, Définir les attributs des widgetsChapitre 18. Définir les attributs des widgets.

 
Sélectionnez
    self.fenetre.set_border_width(10)

À la ligne 52, on crée un bouton et on en enregistre une référence dans self.bouton. Le bouton portera l'étiquette "Salut tout le monde !" lors de son affichage.

 
Sélectionnez
    self.bouton = gtk.Button("Salut tout le monde !")

À la ligne 57, on attache un gestionnaire de signal au bouton, de sorte que la méthode de rappel salut() soit invoquée lorsqu'il émettra le signal "clicked". Nous n'avons aucune donnée à transmettre à salut(), aussi nous passons la valeur None (rien) en lieu de paramètre donnees. Comme l'on pourrait s'y attendre, le signal "clicked" est émis lorsque l'on clique sur le bouton de la souris. Indiquer la valeur du paramètre de données utilisateur None n'est pas exigé et pourrait être omis. On appellerait alors la fonction de rappel avec un paramètre de moins.

 
Sélectionnez
    self.bouton.connect("clicked", self.salut, None)

Nous voulons aussi utiliser ce bouton pour quitter notre programme. Comme nous l'avons déjà vu, le signal "destroy" peut être émis par le gestionnaire de fenêtres, mais également par le programme lui-même, ce qu'illustre la ligne 62. Lorsque l'on clique sur le bouton, celui-ci appelle tout d'abord la méthode de rappel salut(), puis la suivante, dans le même ordre où elles ont été définies. On peut attacher autant de fonctions de rappel que l'on souhaite à un objet, elles seront toutes exécutées dans l'ordre dans lequel on les a connectées.

Puisque nous voulons utiliser la méthode destroy() de GtkWidget et que celle-ci n'accepte qu'un argument (le widget à détruire — la fenêtre dans notre cas), nous employons la méthode connect_object et lui transmettons une référence à notre fenêtre. La méthode connect_object transmettra le paramètre fenêtre comme premier argument au lieu du bouton.

L'appel de la méthode destroy() de gtk.Widget déclenchera l'émission du signal "destroy" par la fenêtre. Ceci entrainera à son tour l'appel de la méthode destroy() de notre classe HelloWorld pour terminer le programme.

 
Sélectionnez
    self.bouton.connect_object("clicked", gtk.Widget.destroy, self.fenetre)

La ligne 65 est un appel de placement, ce que nous verrons en détail un peu plus tard dans le Chapitre 4, Le placement des widgetsChapitre 4. Le placement des widgets. Quoi qu'il en soit, cet appel est assez facile à comprendre : il indique juste à GTK+ que le bouton doit être placé dans la fenêtre, où il s'affichera. À noter qu'un conteneur GTK+ ne peut comporter qu'un seul widget. D'autres widgets, destinés à en recevoir plusieurs, de différentes manières, seront décrits plus loin.

 
Sélectionnez
    self.fenetre.add(self.bouton)

Maintenant que tout est mis en place comme nous le voulions (les gestionnaires de signaux, le bouton placé dans sa fenêtre…), nous demandons à GTK+ d'afficher les widgets à l'écran (lignes 68 et 71). Le widget "fenêtre" est affiché en dernier de sorte qu'il apparaisse avec son bouton déjà placé, et non que la fenêtre s'affiche vide, puis que le bouton apparaisse à l'intérieur, (même si l'on ne s'en apercevrait pas avec un si petit exemple).

 
Sélectionnez
1.
2.
3.
    self.bouton.show()

    self.fenetre.show()

Les lignes 73 à 76 définissent la méthode boucle() qui appelle la fonction gtk.main().

 
Sélectionnez
    def boucle(self):
        gtk.main()

Les lignes 80 à 82 permettent au programme de se lancer automatiquement s'il est appelé directement ou en tant qu'argument de l'interpréteur Python. La ligne 81 crée une instance de la classe HelloWorld et en enregistre une référence dans la variable salut. Enfin, la ligne 82 appelle la méthode boucle() de HelloWorld afin d'initialiser la boucle de traitement d'événements de GTK+.

 
Sélectionnez
1.
2.
3.
    if __name__ == "__main__":
        salut = HelloWorld()
        salut.boucle()

Quand on clique sur un bouton GTK+, le widget émet un signal "clicked". Afin d'utiliser cette information, notre programme prévoit un gestionnaire de signal qui devra la capter et passer le contrôle à une fonction de notre choix. Dans notre exemple, quand on clique sur le bouton créé, la méthode salut() est appelée avec None comme argument. Ensuite, le gestionnaire suivant du signal "clicked" prend la main : il appelle la fonction destroy() du widget avec la fenêtre comme argument, entrainant par là l'émission du signal "destroy" par cette dernière. Ce signal est intercepté et appelle la méthode destroy() de notre classe HelloWorld.

On peut aussi choisir de fermer la fenêtre par le gestionnaire de fenêtres. Le signal "delete_event" sera alors émis et son gestionnaire invoquera la fonction de rappel evnmt_delete(). Si cette dernière renvoie TRUE, la fenêtre sera laissée telle quelle et rien ne se passera. Si, au contraire, elle renvoie FALSE, GTK+ émettra le signal "destroy" qui, évidemment, appellera la fonction de rappel du même nom. Et l'on quittera GTK.


précédentsommairesuivant

Copyright © 2005 John Finlay. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.