III. Chapitre 3. Avançons▲
III-A. Compléments sur les gestionnaires de signaux▲
Regardons à nouveau la méthode connect() :
objet.connect
(
nom, fonction, donnees_fct)
La valeur de retour d'un appel connect() est un marqueur entier qui identifie votre fonction de rappel. Comme nous l'avons déjà vu, il est possible de définir autant de fonctions de rappel que l'on souhaite pour chaque signal et chaque objet ; elles s'exécuteront à tour de rôle, dans l'ordre où elles ont été attachées.
Ce marqueur nous permet de retirer une fonction de rappel de la liste en utilisant :
objet.disconnect
(
marqueur)
Donc, en passant le marqueur renvoyé par l'une des méthodes de connexion du signal, on peut déconnecter un gestionnaire de signal.
On peut aussi désactiver temporairement les gestionnaires de signaux grâce au couple de méthodes signal_handler_block() et signal_handler_unblock() :
2.
3.
objet.signal_handler_block
(
marqueur)
objet.signal_handler_unblock
(
marqueur)
III-B. Modification de notre "Hello World"▲
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.
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# exemple helloworld2.py
import
pygtk
pygtk.require
(
'2.0'
)
import
gtk
class
HelloWorld2:
# Notre fonction de rappel améliorée. Les données
# qui lui sont transmises sont affichées sur stdout.
def
salut
(
self, widget, donnees):
print
"Re-salut ! - Clic sur le
%s
"
%
donnees
# Une autre fonction de rappel
def
evnmt_delete
(
self, widget, evenement, donnees=
None
):
gtk.main_quit
(
)
return
False
def
__init__
(
self):
# Création d'une nouvelle fenêtre
self.fenetre =
gtk.Window
(
gtk.WINDOW_TOPLEVEL)
# Nouvel appel, qui donne le titre "Salut les boutons !"
# à notre nouvelle fenêtre
self.fenetre.set_title
(
"Salut les boutons !"
)
# Ici on définit juste un gestionnaire pour le signal
# delete_event (qui quittera GTK immédiatement)
self.fenetre.connect
(
"delete_event"
, self.evnmt_delete)
# On fixe la largeur des bordures de la fenêtre.
self.fenetre.set_border_width
(
10
)
# On crée une boite pour y placer des widgets. Nous y reviendrons
# en détail dans la section "placement". La boite n'est pas visible,
# c'est juste un outil pour disposer des widgets.
self.boite1 =
gtk.HBox
(
False
, 0
)
# On place la boite dans la fenêtre principale.
self.fenetre.add
(
self.boite1)
# Création d'un nouveau bouton avec l'étiquette "Bouton 1".
self.bouton1 =
gtk.Button
(
"Bouton 1"
)
# Lorsque l'on cliquera sur le bouton, la ligne suivante appellera la
# méthode "salut" avec la chaine "bouton 1" comme argument.
self.bouton1.connect
(
"clicked"
, self.salut, "bouton 1"
)
# Plutôt que add(), on utilise pack_start() afin de placer le bouton
# dans la boite invisible (qui a elle-même été placée dans la fenêtre).
self.boite1.pack_start
(
self.bouton1, True
, True
, 0
)
# N'oubliez pas cette étape, elle fait savoir à GTK que la préparation
# de ce bouton est terminée et qu'il peut maintenant être affiché
self.bouton1.show
(
)
# On répète les mêmes étapes pour créer un second bouton
self.bouton2 =
gtk.Button
(
"Bouton 2"
)
# On appelle la même fonction de rappel, mais avec un argument
# différent : la chaine de caractères "bouton 2".
self.bouton2.connect
(
"clicked"
, self.salut, "bouton 2"
)
self.boite1.pack_start
(
self.bouton2, True
, True
, 0
)
# L'ordre d'affichage des boutons n'est pas très important, mais je conseille
# d'afficher la fenêtre en dernier pour que tout s'affiche d'un seul coup.
self.bouton2.show
(
)
self.boite1.show
(
)
self.fenetre.show
(
)
def
boucle
(
):
gtk.main
(
)
if
__name__
==
"__main__"
:
salut =
HelloWorld2
(
)
boucle
(
)
L'exécution de helloworld2.py produit la fenêtre représentée à la Figure 3.1, « Exemple de "Hello World" amélioré ».
À noter que cette fois, rien n'a été prévu pour sortir du programme, il faut utiliser le gestionnaire de fenêtres ou la ligne de commande. En guise d'exercice, vous pourriez ajouter un troisième bouton "Quitter" qui mettrait fin au programme. Amusez-vous aussi avec les différentes possibilités de la méthode pack_start() en lisant le prochain chapitre. Essayez de redimensionner la fenêtre et observez son comportement.
Voici un bref commentaire des parties du code qui ont changé par rapport à notre premier "Hello World" :
comme précisé plus haut, il n'y a pas de gestionnaire du signal "destroy" dans notre version améliorée.
La fonction de rappel salut() des lignes 13-14 est similaire à celle de la première version. La différence est qu'elle affiche désormais un message contenant les données qu'elle a reçues.
À la ligne 27, on définit une chaine de caractères qui s'affichera dans la barre de titre de la fenêtre (voir Figure 3.1, « Exemple de "Hello World" amélioré »).
La ligne 39 crée une boite horizontale (gtk.HBox) destinée à contenir les deux boutons créés aux lignes 45 et 60. On place cette boite dans le conteneur "fenêtre" à la ligne 42.
Aux lignes 49 et 64, on connecte la méthode salut() au signal "clicked" émis par les boutons. Chaque bouton définit une chaine de caractères différente qui sera transmise à la méthode salut() lors de son appel.
On place les boutons dans la boite horizontale aux lignes 53 et 66 ; ils seront affichés par GTK aux lignes 57 et 70.
Enfin, on affiche la boite et la fenêtre, respectivement aux lignes 71 et 72.