6.2. Botones Biestado (Toggle Buttons)

Los Botones Biestado derivan de los botones normales y son muy similares, excepto que siempre están en uno de dos estados, alternándolos con un clic. Puedan estar presionados, y cuando se vuelva a hacer clic, volverán a su estado inicial, levantados. Se hace clic otra vez y volverán a estar presionados.

Los botones Biestado son la base para los botones de activación y los botones de exclusión mútua, y por ello, muchas de las llamadas usadas con los botones biestado son heredados por los botones de activación y los botones de exclusión mútua. Volveremos a destacar este hecho cuando tratemos esos botones.

Creación de un nuevo botón biestado:

  toggle_button = gtk.ToggleButton(label=None)

Como se puede imaginar, estas llamadas funcionan igual que las llamadas al control de botón normal. Si no se especifica etiqueta el botón estará vacio. El texto de la etiqueta se analiza para comprobar si contiene caracteres mnemotécnicos con el prefijo '_'

Para obtener el estado de un botón biestado, incluyendo los botones de exclusión mútua y los botones de activación, se utiliza el mecanismo del ejemplo anterior. Así se comprueba el estado del biestado, llamando al método get_active() del objeto botón biestado. La señal que nos interesa que emiten los botones biestado (el botón biestado, el botón de activación y el botón de exclusión mútua) es la señal "toggled". Para comprobar el estado de estos botones, se configura un manejador de señales para capturar la señal toggled, y se accede a los atributos del objeto para determinar su estado. La retrollamada será parecida a:

  def toggle_button_callback(widget, data):
      if widget.get_active():
          # Si estamos aqui, el botón biestado está pulsado
      else:
          # Si estamos aqui, el botón biestado está levantado

Para forzar el estado de un botón biestado, y de sus hijos, el botón de exclusión mútua y el botón de activación, se utiliza este método:

  toggle_button.set_active(is_active)

El método anterior puede usarse para forzar el estado del botón biestado, y sus hijos los botones de activación y de exclusión mútua. Especificando un argumento TRUE o FALSE para el parámetro is_active indicamos si el botón debería estar pulsado o levantado. Cuando el botón biestado se crea, su valor predeterminado es levantado o FALSE.

Hay que fijarse en que, cuando se usa el método set_active(), y cambia realmente el estado del botón, se produce la emisión de las señales "clicked" y "toggled" por éste.

  toggle_button.get_active()

Este método devuelve el estado actual del botón biestado como un valor booleano TRUE o FALSE.

El programa togglebutton.py proporciona un ejemplo simple del uso de botones biestado. La figura Figura 6.2, “Ejemplo de Botón Biestado” ilustra la ventana resultante con el segundo botón biestado activo:

Figura 6.2. Ejemplo de Botón Biestado

Ejemplo de Botón Biestado

El código fuente del programa es:

    1	#!/usr/bin/env python
    2	
    3	# ejemplo togglebutton.py
    4	
    5	import pygtk
    6	pygtk.require('2.0')
    7	import gtk
    8	
    9	class ToggleButton:
   10	    # Nuestra retrollamada.
   11	    # Los datos pasados a este método se imprimen a la salida estándar
   12	    def callback(self, widget, data=None):
   13	        print "%s was toggled %s" % (data, ("OFF", "ON")[widget.get_active()])
   14	
   15	    # Esta retrollamada termina el programa
   16	    def delete_event(self, widget, event, data=None):
   17	        gtk.main_quit()
   18	        return gtk.FALSE
   19	
   20	    def __init__(self):
   21	        # Crear una nueva ventana
   22	        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
   23	
   24	        # Establece el título de la ventana
   25	        self.window.set_title("Toggle Button")
   26	
   27	        # Set a handler for delete_event that immediately
   28	        # exits GTK.
   29	        self.window.connect("delete_event", self.delete_event)
   30	
   31	        # Establece el ancho del borde de la ventana
   32	        self.window.set_border_width(20)
   33	
   34	        # Crea una caja vertical
   35	        vbox = gtk.VBox(gtk.TRUE, 2)
   36	
   37	        # Inserta vbox en la ventana principal
   38	        self.window.add(vbox)
   39	
   40	        # Crea el primer botón
   41	        button = gtk.ToggleButton("toggle button 1")
   42	
   43	        # cuando se conmuta el botón llamamos el método "callback"
   44	        # con un puntero a "button" como argumento
   45	        button.connect("toggled", self.callback, "toggle button 1")
   46	
   47	
   48	        # Insertar el botón 1
   49	        vbox.pack_start(button, gtk.TRUE, gtk.TRUE, 2)
   50	
   51	        button.show()
   52	
   53	        # Crear el segundo botón
   54	
   55	        button = gtk.ToggleButton("toggle button 2")
   56	
   57	        # Cuando se conmuta el botón llamamos el método "callback"
   58	        # con un puntero a "button 2" como argumento
   59	        button.connect("toggled", self.callback, "toggle button 2")
   60	        # Insertamos el botón 2
   61	        vbox.pack_start(button, gtk.TRUE, gtk.TRUE, 2)
   62	
   63	        button.show()
   64	
   65	        # Crear el botón "Quit"
   66	        button = gtk.Button("Quit")
   67	
   68	        # Cuando se pulsa el botón llamamos la función main_quit
   69	        # y el programa finaliza
   70	        button.connect("clicked", lambda wid: gtk.main_quit())
   71	
   72	        # Insertar el botón de salida
   73	        vbox.pack_start(button, gtk.TRUE, gtk.TRUE, 2)
   74	
   75	        button.show()
   76	        vbox.show()
   77	        self.window.show()
   78	
   79	def main():
   80	    gtk.main()
   81	    return 0       
   82	
   83	if __name__ == "__main__":
   84	    ToggleButton()
   85	    main()

Las lineas interesantes son la 12-13, que definen el método callback() que imprime la etiqueta del botón biestado y su estado cuando es activado. Las lineas 45 y 59 conectan la señal "toggled" de los botones biestado al método callback().