-
Notifications
You must be signed in to change notification settings - Fork 0
/
ch-MenuWidget.html
208 lines (162 loc) · 12.6 KB
/
ch-MenuWidget.html
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type">
<title>Chapitre 11. Les menus</title>
<link rel="stylesheet" href="pygtktutfr.css" type="text/css">
<meta name="keywords" content="python,pygtk,tutoriel,traduction,menu">
<link rel="start" href="index.html" title="Tutoriel PyGTK 2.0">
<link rel="home" href="index.html" title="Table des matières">
<link rel="up" href="index.html" title="PyGTK 2.0 Tutorial version 1.3">
<link rel="previous" href="sec-PlugsAndSockets.html" title="10.13. Les connexions et connecteurs (Plugs et Sockets)">
<link rel="next" href="sec-ManualMenuExample.html" title="11.2. Démonstration de création manuelle de menus"></head>
<body>
<div class="localisation">
Vous êtes à peu près ici :
<a href="../../index.html">Accueil</a> »
<a href="../pygtktut.php">tutoriel PyGTK</a> »
<a href="index.html">PyGTK : sommaire</a>
</div> <!-- fin localisation -->
<div class="navheader">
<table width="100%" summary="En_tête de navigation">
<tr>
<th colspan="3" align="center">Chapitre 11. Les menus</th></tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="sec-PlugsAndSockets.html">Préc.</a></td>
<th width="60%" align="center"></th>
<td width="20%" align="right"><a accesskey="n" href="sec-ManualMenuExample.html">Suiv.</a></td></tr></table>
<hr>
</div>
<div class="chapter">
<div class="titlepage">
<div><h2 class="title"><a name="ch-MenuWidget"></a>Chapitre 11. Les menus</h2></div></div>
<div class="toc">
<p><b>Sommaire</b></p>
<dl>
<dt>11.1. <a href="ch-MenuWidget.html#menusmanu">Création manuelle de menus</a></dt>
<dt>11.2. <a href="sec-ManualMenuExample.html">Démonstration de création manuelle de menus</a></dt>
<dt>11.3. <a href="sec-UsingItemFactory.html">Création de menus avec l'ItemFactory</a></dt>
<dt>11.4. <a href="sec-ItemFactoryExample.html">Démonstration de l'ItemFactory</a></dt></dl>
</div>
<p>Il y a deux méthodes de création des menus : la facile, et la difficile. Toutes deux ont leur utilité, bien que dans la plupart des cas l'ItemFactory (la méthode facile) suffise. La méthode "difficile" consiste à créer tous les menus en les appelant directement, là où la méthode facile utilisera les appels de <tt>GtkItemFactory</tt>. Même si c'est effectivement beaucoup plus simple, des avantages et des inconvénients existent pour chaque approche.</p>
<p>Il est vrai que l'<tt>Itemfactory</tt> rend nettement plus simple la création et l'ajout ultérieur de menus ; mais faire la même chose manuellement, à l'aide de quelques fonctions, peut apporter beaucoup en termes d'ergonomie. Avec l'<tt>Itemfactory</tt>, vous ne pourrez pas ajouter d'images aux menus, ni y faire figurer le caractère "/".</p>
<div class="sect1">
<div class="titlepage">
<div><h2 class="title" style="clear: both"><a name="MenusManu"></a>11.1. Création manuelle de menus</h2></div>
</div>
<p>Comme le veut la bonne vieille tradition pédagogique, nous commen?s par la méthode difficile :)</p>
<p>Trois widgets entrent en jeu dans la création d'une barre de menus et de ses sous-menus :</p>
<div class="itemizedlist"><ul type="none">
<li style="list-style-type: none"><p>l'entrée de menu, qui représente ce que l'utilisateur veut faire/choisir (par exemple "Enregistrer")</p>
</li><li style="list-style-type: none"><p>le menu, qui contient les entrées de menu</p>
</li><li style="list-style-type: none"><p>la barre de menus, qui contient les menus.</p>
</li></ul></div>
<p>Mais tout n'est pas si simple. En effet, les entrées de menu servent à deux choses différentes : elles représentent à la fois les widgets placés dans le menu et celui placé dans la barre de menu (celui qui, une fois selectionné, active le menu).</p>
<p>Observons les fonctions servant à créer menus et barres de menus :</p>
<pre class="programlisting">
barre_menus = gtk.MenuBar()
</pre>
<p>Cette première fonction, vous l'aurez deviné, crée une nouvelle barre de menus. On utilisera la méthode <tt>add</tt>() de <tt>GtkContainer</tt> pour la placer dans une fenêtre, ou bien les différentes méthodes <tt>pack</tt>() de <tt>GtkBox</tt> pour la placer dans une boite (comme pour les boutons).</p>
<pre class="programlisting">
menu = gtk.Menu()
</pre>
<p>Cette fonction renvoie une référence à un nouveau menu ; il n'est jamais concrètement affiché (par la méthode <tt>show</tt>()), c'est juste un conteneur pour les entrées de menu. Tout ceci vous paraitra, je l'espère, beaucoup plus clair après que vous aurez jeté un œil à l'exemple plus bas.</p>
<p>La fonction ci-dessous sert à créer les entrées qui seront placées dans le menu (et la barre de menus) :</p>
<pre class="programlisting">
entree = gtk.MenuItem(<b><tt>label</tt></b>=None)
</pre>
<p>L'argument <i><tt>label</tt></i> (étiquette), si spécifié, sera parcouru à la recherche de caractères mnémoniques. Cet appel crée les entrées de menu qui doivent apparaitre dans le menu. Attention à ne pas confondre le "menu", créé avec <tt>gtk.Menu</tt>(), et l'"entrée de menu", créée avec la fonction <tt>gtk.MenuItem</tt>(). L'entrée sera un véritable bouton, auquel sera associé une action, tandis que le menu sera un conteneur renfermant des entrées.</p>
<p>Une fois votre entrée créée, vous devez la placer dans un menu grâce à la méthode <tt>append</tt>(). Puis, pour pouvoir réagir à une selection de cette entrée par l'utilisateur, il faudra capter son signal "<tt>activate</tt>" (activer) de la manière habituelle.</p>
<p>Imaginons que nous voulions créer un menu "Fichier" standard, avec les entrées Ouvrir, Enregistrer, et Quitter. Notre code devrait alors ressembler à ceci :</p>
<pre class="programlisting">
menu_fichier = gtk.Menu() # Inutile d'afficher les menus avec show()
# Creation des entrees de menu
entree_ouvrir = gtk.MenuItem("Ouvrir")
entree_enreg = gtk.MenuItem("Enregistrer")
entree_quitter = gtk.MenuItem("Quitter")
# On les place dans le menu
menu_fichier.append(entree_ouvrir)
menu_fichier.append(entree_enreg)
menu_fichier.append(entree_quitter)
# On connecte les fonctions de rappel au signal "activate"
entree_ouvrir.connect_object("activate", entrees_reponse, "fichier.ouvrir")
entree_enreg.connect_object("activate", entrees_reponse, "fichier.enregistrer")
# On peut connecter la entree Quitter à notre fonction de sortie
entree_quitter.connect_object ("activate", destroy, "fichier.quitter")
# Il nous faut afficher les entrees
entree_ouvrir.show()
entree_enreg.show()
entree_quitter.show()
</pre>
<p>Nous avons maintenant notre menu. Il nous reste à créer une barre de menus, puis une entrée "Fichier" à laquelle nous relierons notre menu. Le code pour ce faire est le suivant :</p>
<pre class="programlisting">
barre_menus = gtk.MenuBar()
fenetre.add(barre_menus)
barre_menus.show()
entree_fichier = gtk.MenuItem("Fichier")
entree_fichier.show()
</pre>
<p>Maintenant associons le menu avec <i><tt>entree_fichier</tt></i>. On fait appel pour cela à la méthode suivante :</p>
<pre class="programlisting">
entree.set_submenu(<b><tt>sous_menu</tt></b>)
</pre>
<p>Ce qui donnerait, pour la suite de notre exemple :</p>
<pre class="programlisting">
entree.set_submenu(menu_fichier)
</pre>
<p>Tout ce qui nous reste à faire est de placer le menu dans la barre de menus, en utilisant la méthode :</p>
<pre class="programlisting">
barre_menus.append(<b><tt>enfant</tt></b>)
</pre>
<p>... qui, dans notre cas, donne :</p>
<pre class="programlisting">
barre_menus.append(entree_fichier)
</pre>
<p>Si nous voulions aligner notre menu sur la droite de la barre de menus, comme le sont souvent les menus d'aide, nous pourrions faire appel à la méthode ci-dessous (toujours sur <i><tt>entree_fichier</tt></i> dans notre exemple) avant de l'attacher à la barre de menus.</p>
<pre class="programlisting">
entree.set_right_justified(align_droite)
</pre>
<p>Voici un résumé des étapes nécessaires à la céation d'une barre de menus avec ses menus :</p>
<div class="itemizedlist"><ul type="none">
<li style="list-style-type: none"><p>Créez un nouveau menu avec <tt>gtk.Menu</tt>()</p>
</li><li style="list-style-type: none"><p>Faire un appel à <tt>gtk.MenuItem</tt>() pour chaque entrée que vous voulez voir figurer dans votre menu. Puis utilisez la méthode <tt>append</tt>() pour placer chacune de ces nouvelles entrées dans le menu.</p>
</li><li style="list-style-type: none"><p>Créez une entrée avec <tt>gtk.MenuItem</tt>(). Ce sera la racine du menu, son étiquette apparaitra directement dans la barre de menus.</p>
</li><li style="list-style-type: none"><p>Utilisez la méthode <tt>set_submenu</tt>() pour attacher le menu à l'entrée racine (celle créée à l'étape précédente).</p>
</li><li style="list-style-type: none"><p>Créez une barre de menu avec <tt>gtk.MenuBar</tt>(). Si l'on crée une série de menus que l'on veut placer sur une seule barre de menus, cette étape n'a besoin d'être effectuée qu'une seule fois.</p>
</li><li style="list-style-type: none"><p>Utilisez la méthode <tt>append</tt>() pour placer la racine dans la barre de menus.</p></li>
</ul></div>
<p>Le procédé de création d'un menu popup est plus ou moins identique. La différence est que le menu n'est pas affiché "automatiquement" par une barre de menus, mais explicitement par un appel à la méthode <tt>popup</tt>(), lors d'un évènement "button-press"par exemple. Procédez comme suit :</p>
<div class="itemizedlist"><ul type="none">
<li style="list-style-type: none">
<p>Créez une fonction de rappel gestionnaire d'évènement. Elle doit être de la forme :</p>
<pre class="programlisting">
def fct_rappel(widget, evenement):
</pre>
</li><li style="list-style-type: none">
<p>... et utilisera l'évènement pour savoir où afficher le menu.</p>
</li><li style="list-style-type: none">
<p>Dans le gestionnaire d'évènement, si l'évènement est une pression d'un bouton de la souris, traitez le comme un évènement bouton (ce qu'il est) et utilisez-le comme montré dans l'exemple de code pour transmettre l'information à la méthode <tt>popup</tt>().</p>
</li><li style="list-style-type: none">
<p>Attachez ce gestionnaire d'évènement à un widget ainsi :</p>
<pre class="programlisting">
widget.connect_object("evenement", fct_rappel, menu)
</pre>
</li><li style="list-style-type: none">
<p>... où <i>widget</i> est le widget auquel vous connectez l'évènement, <i>fct_rappel</i> la fonction de rappel, et <i>menu</i> le menu crée par <tt>GtkMenu</tt>(). Ce dernier peut aussi être affiché par une barre d'état, comme dans notre code.</p></li>
</ul>
</div></div></div>
<div class="navfooter">
<hr>
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="sec-PlugsAndSockets.html">Préc.</a></td>
<td width="20%" align="center"><a accesskey="u" href="index.html">Chapitre parent</a></td>
<td width="40%" align="right"><a accesskey="n" href="sec-ManualMenuExample.html">Suiv.</a></td></tr>
<tr>
<td width="40%" align="left" valign="top">10.13. Les connexions et connecteurs (Plugs et Sockets)</td>
<td width="20%" align="center"><a accesskey="h" href="index.html">Table des matières</a></td>
<td width="40%" align="right" valign="top">11.2. Démonstration de création manuelle de menus</td>
</tr></table>
</div>
</body>
</html>