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.
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 :
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 apparaitre à 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 :
- --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).
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.
Les variables et fonctions du module PyGTK portent toutes un nom de la forme gtk.*. Par exemple, le programme helloworld.py fait appel à :
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 :
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 :
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 :
def
meth_rappel
(
self, widget, donnees_meth):
où 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 :
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 :
def
fct_rappel
(
objet)
def
meth_rappel
(
self, objet)
où 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 :
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 :
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 :
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 :
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 :
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 :
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é.
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é :
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.
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.
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.
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.
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.
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.
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.
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.
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).
2.
3.
self.bouton.show
(
)
self.fenetre.show
(
)
Les lignes 73 à 76 définissent la méthode boucle() qui appelle la fonction gtk.main().
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+.
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.