Voilà pour la théorie. Maintenant, jetons un œil du côté de l'exemple menu.py pour tenter de clarifier un peu tout ça. La Figure 11.1 nous montre la fenetre du programme :
Le code source de menu.py est le suivant :
1 #!/usr/bin/env python
2
3 # exemple menu.py
4
5 import pygtk
6 pygtk.require('2.0')
7 import gtk
8
9 class ExempleMenu:
10 def __init__(self):
11 # Creation d'une fenetre
12 fenetre = gtk.Window(gtk.WINDOW_TOPLEVEL)
13 fenetre.set_size_request(200, 100)
14 fenetre.set_title("Test menu GTK")
15 fenetre.connect("delete_event", gtk.main_quit)
16
17 # Initialisation du widget. Souvenez-vous : on n'affiche jamais
18 # (avec show()) le widget menu !
19 # Il s'agit du menu qui contiendra les commandes, celui qui apparaitra
20 # apres un clic sur le "Menu racine" de l'application.
21 menu = gtk.Menu()
22
23 # Ensuite, on ecrit une petite boucle qui cree trois entrees pour le menu.
24 # Notez l'appel a gtk_menu_append. Ici, nous ajoutons une liste de commandes
25 # a notre menu. Nous devrions aussi nous debrouiller pour capter le signal
26 # "clicked" de chacune des commandes et mettre en place une fonction de rappel
27 # pour le traiter, mais pour ne pas faire trop long on s'en passera ici.
28 for i in range(3):
29 # On copie les noms dans une variable "tampon".
30 tampon = "Sous-menu test - %d" % i
31
32 # On cree une nouvelle commande , avec un nom...
33 commandes = gtk.MenuItem(tampon)
34
35 # ... et on l'ajoute au menu
36 menu.append(commandes)
37
38 # On reagit a la selection de la commande
39 commandes.connect("activate", self.reponse_commande, tampon)
40
41 # On affiche le widget
42 commandes.show()
43
44 # Voici le menu racine. Ce sera aussi l'etiquette visible dans la barre de
45 # menus. On ne lui connecte pas de gestionnaire de signal, son role etant
46 # seulement de faire apparaitre le reste du menu lorsqu'on le clique.
47 menu_racine = gtk.MenuItem("Menu racine")
48
49 menu_racine.show()
50
51 # Ici on indique que notre "menu" cree plus haut doit etre le menu de
52 # "Menu racine"
53 menu_racine.set_submenu(menu)
54
55 # Une boite verticale pour y placer un menu et un bouton :
56 boitev = gtk.VBox(False, 0)
57 fenetre.add(boitev)
58 boitev.show()
59
60 # On cree une barre pour contenir les menus, et on la place dans notre fenetre
61 barre_menus = gtk.MenuBar()
62 boitev.pack_start(barre_menus, False, False, 2)
63 barre_menus.show()
64
65 # Creation d'un bouton, auquel on attache le menu comme popup
66 bouton = gtk.Button("Cliquez-moi")
67 bouton.connect_object("event", self.evnmt_button_press, menu)
68 boitev.pack_end(bouton, True, True, 2)
69 bouton.show()
70
71 # Enfin, on rattache la commande a la barre de menus -- il s'agit de la commande
72 # "Menu racine" sur laquelle je me suis emballe =)
73 barre_menus.append (menu_racine)
74
75 # Toujours afficher la fenetre en dernier, afin qu'elle soit complete lors de
76 # son apparition a l'ecran.
77 fenetre.show()
78
79 # On repond a l'evenement "button-press" en affichant un menu, qui est
80 # transmis comme "widget".
81 # Notez que l'argument "widget" N'EST PAS le bouton qui a ete enfonce,
82 # mais bien le menu a afficher
83 def evnmt_button_press(self, widget, evenement):
84 if evenement.type == gtk.gdk.BUTTON_PRESS:
85 widget.popup(None, None, None, evenement.button, evenement.time)
86 # On fait savoir au code appelant que l'on a traite l'evenement. Son
87 # histoire s'arrete ici.
88 return True
89 # On fait savoir au code appelant que l'evenement n'a pas ete traite. Il continue.
90 return False
91
92 # Affiche une chaine de caracteres lorsqu'une commande est selectionnee.
93 def reponse_commande(self, widget, chaine):
94 print "%s" % chaine
95
96 def main():
97 gtk.main()
98 return 0
99
100 if __name__ == "__main__":
101 ExempleMenu()
102 main()
Vous pouvez aussi n'affecter aucune réaction à la sélection d'une entree de menu, et, par l'intermédiaire d'une table de raccourcis clavier, lier certaines touches aux fonctions de rappel du menu.