10.11. Barra de Herramientas (Toolbar)

Las Toolbars (Barras de Herramientas) se usan normalmente para agrupar un número de controles y simplificar la personalización de su apariencia y disposición. Típicamente una barra de herramientas consiste en botones con iconos, etiquetas y pistas, pero se puede poner cualquier otro control en una barra de herramientas. Finalmente, los elementos se pueden colocar horizontal o verticalmente y se pueden ver los botones con iconos, texto, o ambos.

La creación de una barra de herramientas se consigue (como uno podría sospechar) con la siguiente función:

  toolbar = gtk.Toolbar()

Después de crear una barra de herramientas uno puede añadir al principio, al final o en otro posición, items (textos simples) o elementos (cualquier tipo de control) en la barra de herramientas. Para describir un item necesitamos un texto, un texto para la pista, un texto privado para la pista, un icono para el botón y una retrollamada. Por ejemplo, para añadir al principio o al final un item se pueden usar los siguientes métodos:

  toolbar.append_item(text, tooltip_text, tooltip_private_text, icon, callback, user_data=None)

  toolbar.prepend_item(text, tooltip_text, tooltip_private_text, icon, callback, user_data)

Si se quiere usar el método insert_item(), el único parámetro adicional que debe especificarse, es la posición en la cual el elemento se debe insertar. Así:

  toolbar.insert_item(text, tooltip_text, tooltip_private_text, icon, callback, 
                      user_data, position)

Para añadir de forma sencilla espacios entre items de la barra de herramientas se pueden usar los siguientes métodos:

  toolbar.append_space()

  toolbar.prepend_space()

  toolbar.insert_space(position)

Si es necesario, la orientación de una barra de herramientas, su estilo y el hecho de que las pistas estén disponibles, se puede cambiar sobre la marcha usando los siguientes métodos:

  toolbar.set_orientation(orientation)

  toolbar.set_style(style)

  toolbar.set_tooltips(enable)

Donde la orientation puede ser ORIENTATION_HORIZONTAL u ORIENTATION_VERTICAL. El style se usa para especificar la apariencia de la barra de herramientas y puede ser TOOLBAR_ICONS (iconos), TOOLBAR_TEXT (texto), o TOOLBAR_BOTH (ambos). El argumento enable puede ser o TRUE o FALSE.

Para mostrar algunas otras cosas que se pueden hacer con una barra de herramientas veamos el siguiente programa de ejemplo toolbar.py (interrumpiremos el listado con explicaciones adicionales):

    1   #!/usr/bin/env python
    2
    3   # ejemplo toolbar.py
    4
    5   import pygtk
    6   pygtk.require('2.0')
    7   import gtk
    8
    9   class ToolbarExample:
   10       # Este método se conecta al botón Close o
   11       # al cierre de la ventana desde el Gestor de Ventanas
   12       def delete_event(self, widget, event=None):
   13           gtk.main_quit()
   14           return gtk.FALSE
   15

Este principio debería resultar familiar si no es el primer programa PyGTK. No obstante hay una cosa más, vamos a importar un bonito dibujo XPM (gtk.xpm) para que nos sirva de icono para todos los botones. La linea 10 empieza la clase de ejemplo ToolbarExample y las lineas 12-14 definen el método de retrollamada que finalizará el programa.

   16	    # es fácil... cuando se conmuta uno de los botones, simplemente
   17	    # comprobamos cuál está activo y cambiamos el estilo de la barra de herramientas
   18	    # de acuerdo con ello
   19       def radio_event(self, widget, toolbar):
   20           if self.text_button.get_active():
   21               toolbar.set_style(gtk.TOOLBAR_TEXT)
   22           elif self.icon_button.get_active():
   23               toolbar.set_style(gtk.TOOLBAR_ICONS)
   24           elif self.both_button.get_active():
   25               toolbar.set_style(gtk.TOOLBAR_BOTH)
   26
   27	    # incluso más fácil, comprobamos la conmutación del botón
   28	    # y activamos/desactivamos las pistas
   29	    def toggle_event(self, widget, toolbar):
   30	        toolbar.set_tooltips(widget.get_active())
   31

Las lineas 19-30 son dos métodos de retrollamada que se llamarán cuando uno de los botones de la barra de herramientas se active. Estas cosas resultan familiares si ya se han usado botones biestado (y botones de exclusión mútua).

   32       def __init__(self):
   33           # Aquí está la ventana principal (un diálogo) y el asa
   34           # necesitamos una barra de herramientas, un icono con máscara (uno para todos
   35           # los botones) y un control de icono en el que ponerlo (aunque crearemos
   36           # un control aparte para cada botón)
   37           # creamos una nueva ventana con su título y un tamaño adecuado
   38           dialog = gtk.Dialog()
   39           dialog.set_title("GTKToolbar Tutorial")
   40           dialog.set_size_request(450, 250)
   41           dialog.set_resizable(gtk.TRUE)
   42
   43           # generalmente querremos salir si cierran la ventana
   44           dialog.connect("delete_event", self.delete_event)
   45
   46           # para que tenga mejor aspecto ponemos la barra en la caja con asa
   47           # de manera que se pueda separar de la ventana principal
   48           handlebox = gtk.HandleBox()
   49           dialog.vbox.pack_start(handlebox, gtk.FALSE, gtk.FALSE, 5)
   50

Lo anterior debería ser común a cualquier otra aplicación PyGTK. Inicialización de una instancia de ToolbarExample, creación de la ventana, etc. Sólo hay una cosa que probablemente necesite más explicación: una caja con mango (asa) (HandleBox). Una caja con mango es simplemente otra caja cualquiera que puede usarse para meter controles dentro. La diferencia entre ella y las cajas típicas es que puede despegarse de la ventana padre (o, de hecho, la caja con mango permanece en el padre, pero se reduce a un rectángulo muy pequeño, mientras que todos sus contenidos cambian de padre a una nueva ventana flotante). Normalmente es bueno tener una barra de herramientas separable, por lo que estos dos controles suelen ir juntos normalmente.

   51           # la barra de herramientas será horizontal, con iconos y texto, y
   52           # con espacios de 5pxl entre elementos y, finalmente,
   53           # la insertaremos en la caja con asa
   54           toolbar = gtk.Toolbar()
   55           toolbar.set_orientation(gtk.ORIENTATION_HORIZONTAL)
   56           toolbar.set_style(gtk.TOOLBAR_BOTH)
   57           toolbar.set_border_width(5)
   58           handlebox.add(toolbar)
   59

Bien, lo que hacemos arriba es una simple inicialización del control de la barra de herramientas.

   60           # nuestro primer elemento es el botón <close>
   61           iconw = gtk.Image() # control de icono
   62           iconw.set_from_file("gtk.xpm")
   63           close_button = toolbar.append_item(
   64               "Close",           # etiqueta de botón
   65               "Closes this app", # la pista del botón
   66               "Private",         # información privada de la pista
   67               iconw,             # control icono
   68               self.delete_event) # una señal
   69           toolbar.append_space() # espacio tras el elemento
   70

En el código anterior se puede ver el caso más simple: añadir un botón a la barra de herramientas. Justo antes de añadir el nuevo elemento, tenemos que construir un control de imágen que servirá como icono para este elemento; este paso tiene que repetirse para cada nuevo elemento. Justo después del elemento añadimos también espacio, para que los elementos siguientes no se toquen unos a otros. Como se puede ver, el método append_item() devuelve una referencia al control de botón recién creado, para que se pueda trabajar con él de la forma habitual.

   71           # ahora, hagamos el grupo de botones de exclusión...
   72           iconw = gtk.Image() # control de icono
   73           iconw.set_from_file("gtk.xpm")
   74           icon_button = toolbar.append_element(
   75               gtk.TOOLBAR_CHILD_RADIOBUTTON, # type of element
   76               None,                          # control
   77               "Icon",                        # etiqueta
   78               "Only icons in toolbar",       # pista
   79               "Private",                     # cadena privada de pista
   80               iconw,                         # icono
   81               self.radio_event,              # señal
   82               toolbar)                       # datos para la señal
   83           toolbar.append_space()
   84           self.icon_button = icon_button
   85

Aqui empezamos a crear un grupo de botones de exclusión mútua. Para hacer esto usamos el método append_element() . De hecho, usando este método, uno puede también puede añadir items normales o incluso espacios (type = gtk.TOOLBAR_CHILD_SPACE (espacio) o gtk.TOOLBAR_CHILD_BUTTON (botón)). En el ejemplo anterior hemos empezado a crear un grupo de botones de exclusión mútua. Cuando se crean otros botones de exclusión mútua se necesita una referencia al botón anterior en el grupo, para que se pueda construir una lista de botones fácilmente (mira la sección RadioButtons de este tutorial). También tenemos una referencia al botón en la instancia de ToolbarExample para acceder a él más tare.

   86           # los siguientes botones de exclusión se refieren a los anteriores
   87           iconw = gtk.Image() # control de icono
   88           iconw.set_from_file("gtk.xpm")
   89           text_button = toolbar.append_element(
   90               gtk.TOOLBAR_CHILD_RADIOBUTTON,
   91               icon_button,
   92               "Text",
   93               "Only texts in toolbar",
   94               "Private",
   95               iconw,
   96               self.radio_event,
   97               toolbar)
   98           toolbar.append_space()
   99           self.text_button = text_button
  100
  101           iconw = gtk.Image() # control de icono
  102           iconw.set_from_file("gtk.xpm")
  103           both_button = toolbar.append_element(
  104               gtk.TOOLBAR_CHILD_RADIOBUTTON,
  105               text_button,
  106               "Both",
  107               "Icons and text in toolbar",
  108               "Private",
  109               iconw,
  110               self.radio_event,
  111               toolbar)
  112           toolbar.append_space()
  113           self.both_button = both_button
  114           both_button.set_active(gtk.TRUE)
  115

Creamos otros botones de exclusión mútua de la misma forma excepto que le pasamos uno de los botones creados al método append_element() para especificar el grupo.

Al final tenemos que establecer el estado de uno de los botones manualmente (si no todos tienen el estado activo, impidiéndonos que los vayamos intercambiando).

  116           # aquí ponemos simplemente un botón biestado
  117           iconw = gtk.Image() # control de icono
  118           iconw.set_from_file("gtk.xpm")
  119           tooltips_button = toolbar.append_element(
  120               gtk.TOOLBAR_CHILD_TOGGLEBUTTON,
  121               None,
  122               "Tooltips",
  123               "Toolbar with or without tips",
  124               "Private",
  125               iconw,
  126               self.toggle_event,
  127               toolbar)
  128           toolbar.append_space()
  129           tooltips_button.set_active(gtk.TRUE)
  130

Un botón biestado se puede crear de la forma obvia (si ya se han creado botones de exclusión mútua alguna vez).

  131           # para empaquetar un control en la barra, solamente tenemos
  132           # crearlo y añadirlo con una pista apropiada
  133           entry = gtk.Entry()
  134           toolbar.append_widget(entry,  "This is just an entry", "Private")
  135
  136           # bien, no está creada dentro de la barra, así que tenemos que mostrarla
  137           entry.show()
  138

Como se puede ver, añadir cualquier tipo de control a una barra de herramientas es fácil. La única cosa que se tiene que recordar es que este control debe mostrarse manualmente (al contrario que los elementos, que se mostrarán de golpe con la barra de herramientas).

  139           # ¡ya está! Mostremos todo.
  140           toolbar.show()
  141           handlebox.show()
  142           dialog.show()
  143
  144   def main():
  145       # nos quedamos en gtk_main y ¡esperamos que empiece la diversión!
  146       gtk.main()
  147       return 0
  148
  149   if __name__ == "__main__":
  150       ToolbarExample()
  151       main()

La linea 142 termina la definición de la clase ToolbarExample. Las lineas 144-147 definen la función main() que simplemente llama a la función gtk.main() para iniciar el bucle de procesamiento de eventos. Las lineas 149-151 crean una instancia de ToolbarExample y luego entran en el bucle de procesamiento de eventos. Así termina el tutorial de la barra de herramientas. Por supuesto, para apreciarla en su máximo esplendor se necesita también el icono XPM, gtk.xpm. La figura Figura 10.8, “Ejemplo de Barra de Herramientas” muestar la ventana resultante:

Figura 10.8. Ejemplo de Barra de Herramientas

Ejemplo de Barra de Herramientas