Capítulo 11. Control Menú

Tabla de contenidos

11.1. Creación Manual de Menús
11.2. Ejemplo de Menú Manual
11.3. Uso de la Factoria de Elementos
11.4. Ejemplo de Factoria de Elementos - ItemFactory

Hay dos formas de crear menús: la forma fácil y la dificil. Cada una tiene sus usos, pero normalmente se puede usar el Itemfactory (Factoria de Elementos) (la forma fácil). La forma "difícil" consiste en crear los menús usando llamadas directamente, mientras que de la forma fácil se hacen llamadas a GtkItemFactory. Esto último es mucho más simple, pero cada enfoque tiene sus ventajas y desventajas.

La Itemfactory es mucho más fácil de usar, y más fácil de añadir menús, aunque escribir unas cuantas funciones auxiliares para crear menús usando el método manual puede ser más ventajoso de cara a la usabilidad. Por ejemplo, con Itemfactory, no es posible añadir imágenes o el carácter '/' a los menús.

11.1. Creación Manual de Menús

Siguiendo la tradición docente, veremos primero la forma difícil. :)

Hay tres controles involucrados en la creación de una barra de menús y de submenús:

  • un elemento de menú, que es lo que el usuario va a seleccionar, por ejemplo, "Guardar"

  • un menú, que actua como contenedor para elementos de menú, y

  • una barra de menú, que sirve de contenedor para cada uno de los menús individuales.

Esto es algo complicado por el hecho de que los controles de elementos de menú se usan para dos cosas distintas. Son tanto los controles que se colocan en el menú, y el control que se coloca en la barra de menú, que, cuando se selecciona, activa el menú.

Veamos las funciones que se usan para crear menús y barras de menús. La primera función se usa para crear una nueva barra de menú:

  menu_bar = gtk.MenuBar()

Esta función bastante autoexplicativa crea una nueva barra de menús. Se puede usar el método gtk.Container add() para meter la barra de menús en una ventana, o los métodos pack de gtk.Box para meterlo en una caja - igual que los botones.

  menu = gtk.Menu()

Esta función devuelve una referencia a un nuevo menú; nunca se mostrará (con el método show() ), es sólo un contenedor para elementos de menús. Esto se aclarará más cuando se vea el ejemplo que aparece más abajo.

La siguiente función se usa para crear elementos de menús que se colocan en el menú (y la barra de menús):

  menu_item = gtk.MenuItem(label=None)

El parámetro label, si existe, se analizará buscando caracteres mnemónicos. Esta llamada se usa para crear los elementos de menú que se van a visualizar. Debe recordarse la diferenciar entre un "menú" como el que se crea con la función gtk.Menu() y un "elemento de menú" como el que se crea con gtk.MenuItem() . El elemento de menú será en realidad un botón con una acción asociada, mientras que un menú será un contenedor que contiene elementos de menú.

Una vez se ha creado un elemento de menú es preciso meterlo en un menú. Esto se consigue con el método append() . Para poder saber cuándo el usuario selecciona un elemento, se necesita conectarlo a la señal "activate" de la forma habitual. Por tanto, si se quiere crear un menú estándar Archivo, con las opciones Abrir, Guardar, y Salir, el código sería algo asi como:

  file_menu = gtk.Menu()    # No necesitamos mostrar los menús

  # Creamos los elementos de menú
  open_item = gtk.MenuItem("Abrir")
  save_item = gtk.MenuItem("Guardar")
  quit_item = gtk.MenuItem("Salir")

  # Los añadimos al menú
  file_menu.append(open_item)
  file_menu.append(save_item)
  file_menu.append(quit_item)

  # Se conectan las funciones de retrollamada a la señal "activate"
  open_item.connect_object("activate", menuitem_response, "file.open")
  save_item.connect_object("activate", menuitem_response, "file.save")

  # se conecta el elemento quit a nuestra función de salida
  quit_item.connect_object ("activate", destroy, "file.quit")

  # Mostramos los elementos de menú
  open_item.show()
  save_item.show()
  quit_item.show()

En este punto tenemos nuestro menú. Ahora es necesario crear una barra de menú y un elemento de menú para la entrada Archivo, al que añadiremos nuestro menú. El código es el siguiente:

  menu_bar = gtk.MenuBar()
  window.add(menu_bar)
  menu_bar.show()

  file_item = gtk.MenuItem("Archivo")
  file_item.show()

Ahora necesitamos asociar el menú con file_item. Esto se hace con el método:

  menu_item.set_submenu(submenu)

Por tanto, nuestro ejemplo continuaría así:

  menu_item.set_submenu(file_menu)

Lo único que nos queda es añadir el menú a la barra de menús, lo cual se consigue con el método:

  menu_bar.append(child)

que en nuestro caso es así:

  menu_bar.append(file_item)

Si queremos el menú justificado a la derecha en la barra de menús, como suelen ser los menús de ayuda, podemos usar el siguiente método (de nuevo en file_item en nuestro ejemplo) antes de añadirlo a la barra de menús.

  menu_item.set_right_justified(right_justified)

Aqui tenemos un resumen de los pasos necesarios para crear una barra de menús con menús en ella:

  • Se crea un nuevo menú con gtk.Menu()

  • Se hacen varias llamadas a gtk.MenuItem(), una para cada elemento que se quiera tener en el menú. Y se usa el método append() para poner cada uno de estos elementos en el menú.

  • Se crea un elemento de menú usando gtk.MenuItem(). Este será la raiz del menú, el texto que aparezca en él estará en la propia barra de menús.

  • Se usa el método set_submenu() para añadir el menú al elemento raiz del menú (el creado en el paso anterior).

  • Se crea una nueva barra de menús con gtk.MenuBar(). Este paso se hace únicamente una vez al crear una serie de menús en una barra de menús.

  • Se usa el método append() para poner el menú raiz en la barra de menús.

La creación de un menú emergente es prácticamente igual. La diferencia es que el menú no se visualiza "automáticamente" por una barra de menús, sino explícitamente llamando al método popup() desde un evento de pulsación de botón, por ejemplo. Se han de seguir estos pasos:

  • Se crea una retrollamada que maneje el evento con el siguiente formato:

      def handler(widget, event):
    
  • y usará el evento para saber donde mostrar el menú.

  • En el manejador del evento, si el evento es una pulsación de botón, se trata el evento como un evento de botón (realmente lo es) y se usa como en el código de ejemplo para pasar información al método popup() .

  • Se enlaza el manejador del evento al control con:

      widget.connect_object("event", handler, menu)
    
  • donde widget es el control al que se está conectando, handler es la función manejadora, y menu es un menú creado con gtk.Menu(). Esto puede ser un menú que también está en una barra de menús, tal como se muestra en el código de ejemplo.