3. Chapitre 3. Avançons▲
3-1. 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)
3-2. 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
boîte
pour
y
placer
des
widgets.
Nous
y
reviendrons
#
en
détail
dans
la
section
"placement".
La
boîte
n'est
pas
visible,
#
c'est
juste
un
outil
pour
disposer
des
widgets.
self.boite1 =
gtk.HBox
(
False
, 0
)
#
On
place
la
boîte
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
chaîne
"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
boîte
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
chaîne
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 chaîne 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 boîte horizontale (gtk.HBox) destinée à contenir les deux boutons créés aux lignes 45 et 60. On place cette boîte dans le conteneur "fenetre" à 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 chaîne de caractères différente qui sera transmise à la méthode salut() lors de son appel.
On place les boutons dans la boîte horizontale aux lignes 53 et 66 ; ils seront affichés par GTK aux lignes 57 et 70.
Enfin, on affiche la boîte et la fenêtre, respectivement aux lignes 71 et 72.