11.2. Ejemplo de Menú Manual

Esto es más o menos lo que hace falta. Veamos el programa de ejemplo menu.py para ayudarnos a clarificar los conceptos. La figura Figura 11.1, “Ejemplo de Menú” muestra la ventana del programa:

Figura 11.1. Ejemplo de Menú

Ejemplo de Menú

El código fuente de menu.py es:

    1	#!/usr/bin/env python
    2	
    3	# ejemplo menu.py
    4	
    5	import pygtk
    6	pygtk.require('2.0')
    7	import gtk
    8	
    9	class MenuExample:
   10	    def __init__(self):
   11	        # create a new window
   12	        window = gtk.Window(gtk.WINDOW_TOPLEVEL)
   13	        window.set_size_request(200, 100)
   14	        window.set_title("GTK Menu Test")
   15	        window.connect("delete_event", lambda w,e: gtk.main_quit())
   16	
   17	        # Se inicia el control menú, y se ha de recordar que ¡¡NUNCA
   18	        # se debe mostrar con show() este control!! 
   19	        # Este es el menú que contiene los elementos de menú, el que
   20	        # se desplegará al pulsar en "Root Menu" en la aplicación
   21	        menu = gtk.Menu()
   22	
   23	        # Después un pequeño bucle construye tres entradas de menú para
   24	        # "test-menu".  Obsérvese la llamada a gtk_menu_append.  Aquí vamos
   25	        # añadiendo una lista de elementos de menú a nuestro menú.  Normalmente también
   26	        # interceptaríamos la señal "clicked" para cada uno de los elementos de menú y
   27	        # se establecería una retrollamada para ellas, pero se omiten aquí para ahorrar espacio
   28	        for i in range(3):
   29	            # Copiar los nombres a buf
   30	            buf = "Test-undermenu - %d" % i
   31	
   32	            # Crear un nuevo elemento de menú con nombre...
   33	            menu_items = gtk.MenuItem(buf)
   34	
   35	            # ...y lo añadimos al menú
   36	            menu.append(menu_items)
   37	
   38		    # Hacemos algo interesante cuando se selecciona el elemento de menú
   39		    menu_items.connect("activate", self.menuitem_response, buf)
   40	
   41	            # Mostramos el control
   42	            menu_items.show()
   43	
   44	        # Este es el menú raíz, y será la etiqueta mostrada en la barra de menú
   45	        # No tendrá un manejador de señal asociado, puesto que únicamente
   46	        # muestra el resto del menú al pulsarlo.
   47	        root_menu = gtk.MenuItem("Root Menu")
   48	
   49	        root_menu.show()
   50	
   51	        # Ahora especificamos que queremos que nuestro recien creado "menu" sea el
   52	        # menú del menú raíz "root menu"
   53	        root_menu.set_submenu(menu)
   54	
   55	        # Una vbox para poner un menú y un botón en él:
   56	        vbox = gtk.VBox(gtk.FALSE, 0)
   57	        window.add(vbox)
   58	        vbox.show()
   59	
   60	        # Creamos una barra de menú para los menús, que añadimos a la ventana principal
   61	        menu_bar = gtk.MenuBar()
   62	        vbox.pack_start(menu_bar, gtk.FALSE, gtk.FALSE, 2)
   63	        menu_bar.show()
   64	
   65	        # Creamos un botón al que añadir el menú emergente
   66	        button = gtk.Button("press me")
   67	        button.connect_object("event", self.button_press, menu)
   68	        vbox.pack_end(button, gtk.TRUE, gtk.TRUE, 2)
   69	        button.show()
   70	
   71	        # Y finalmente añadimos el elemento de menú a la barra de menú. Este es el 
   72	        # elemento de menú raíz del que hemos estado hablando =)
   73	        menu_bar.append (root_menu)
   74	
   75	        # siempres mostramos la ventana como último paso, de manera que se dibuja todo
   76	        # de una vez.
   77	        window.show()
   78	
   79	    # Respondemos a una pulsación de botón con un menú pasado como control "widget"
   80	    #
   81	    # Nótese que el argumento "widget" es el menú pasado, NO
   82	    # el botón que fue pulsado.
   83	    def button_press(self, widget, event):
   84	        if event.type == gtk.gdk.BUTTON_PRESS:
   85	            widget.popup(None, None, None, event.button, event.time)
   86	            # Notificamos al código de llamada que hemos manejado este evento.
   87	            # La cola acaba aquí.
   88	            return gtk.TRUE
   89	        # Notificamos al código de llamada que no manejamos este evento. La cola continúa.
   90	        return gtk.FALSE
   91	
   92	    # Imprimimos una cadena cuando se selecciona un elemento de menú
   93	    def menuitem_response(self, widget, string):
   94	        print "%s" % string
   95	
   96	def main():
   97	    gtk.main()
   98	    return 0
   99	
  100	if __name__ == "__main__":
  101	    MenuExample()
  102	    main()

También se puede hacer un elemento de menú insensible y, usando una tabla de atajos (aceleradores), conectar teclas a retrollamadas de menús.