9.4. Barras de Progreso (ProgressBar)

Las barras de progreso se usan para mostrar el estado de una operación. Son bastante fáciles de usar, como se verá en el código que sigue. Pero primero empecemos con una llamada para crear una nueva barra de progreso.

  progressbar = gtk.ProgressBar(adjustment=None)

El argumento adjustment (ajuste) especifica un ajuste para usarlo con la barra de progreso progressbar. Si no se especifica se creará un ajuste. Ahora que la barra de progreso está creada ya podemos usarla.

  progressbar.set_fraction(fraction) 

El objeto progressbar es la barra de progreso con la que queremos operar, y el argumento (fraction) es la cantidad "completada", lo que significa la cantidad con la que se ha rellenado la barra de progreso desde 0 a 100%. Esto se le pasa al método como un número real entre 0 y 1.

Una barra de progreso puede orientarse de diversas formas usando el método:

  progressbar.set_orientation(orientation) 

El argumento orientation puede tomar uno de los siguientes valores para indicar la dirección en la que la barra de progreso se mueve:

  PROGRESS_LEFT_TO_RIGHT  # izquierda a derecha
  PROGRESS_RIGHT_TO_LEFT  # derecha a izquierda
  PROGRESS_BOTTOM_TO_TOP  # abajo a arriba
  PROGRESS_TOP_TO_BOTTOM  # arriba a abajo

Además de indicar la cantidad de progreso que se ha completado, la barra de progreso también puede usarse simplemente para indicar que ha habido alguna actividad. Esto puede ser útil en situaciones donde el progreso no se puede medir con un rango de valores. La siguiente función indica que se ha hecho algún progreso.

  progressbar.pulse()

El tamaño de paso de un indicador de actividad se establece usando la siguiente función, donde la fracción es un número entre 0.0 y 1.0.

  progressbar.set_pulse_step(fraction)

Cuando no está en el modo actividad, la barra de progreso también puede mostrar una cadena de texto en su canal, usando el siguiente método:

  progressbar.set_text(text)

Nota

Téngase en cuenta que set_text() no soporta el formateo de texto al estilo printf() como lo hacía la barra de progreso de GTK+ 1.2.

Se puede desactivar la visualización de la cadena llamando a set_text() de nuevo sin argumentos.

La cadena de texto actual de la barra de progreso se puede obtener con el siguiente método:

  text = progressbar.get_text()

Normalmente las Barras de Progreso usan cronómetros u otras funciones parecidas (mira la sección sobre Cronómetros, E/S y Funciones de Inactividad) para dar la ilusión de multitarea. Todas usarán los métodos set_fraction() o pulse() de la misma forma.

El programa progressbar.py proporciona un ejemplo de barra de progreso, actualizada usando cronómetros. Este código también muestra como reiniciar la Barra de Progreso. La figura Figura 9.4, “Ejemplo de Barra de Progreso” muestra la ventana resultante:

Figura 9.4. Ejemplo de Barra de Progreso

Ejemplo de Barra de Progreso

El código fuente del programa progressbar.py es:

    1	#!/usr/bin/env python
    2	
    3	# ejemplo progressbar.py
    4	
    5	import pygtk
    6	pygtk.require('2.0')
    7	import gtk
    8	
    9	# Actualizar el valor de la barra de progreso de manera
   10	# que tengamos algo de movimiento
   11	def progress_timeout(pbobj):
   12	    if pbobj.activity_check.get_active():
   13	        pbobj.pbar.pulse()
   14	    else:
   15	        # Calcular el valor de la barra de progreso usando el
   16	        # valor del rango establecido en el objeto ajuste
   17	        new_val = pbobj.pbar.get_fraction() + 0.01
   18	        if new_val > 1.0:
   19	            new_val = 0.0
   20	        # Fijar el nuevo valor
   21	        pbobj.pbar.set_fraction(new_val)
   22	
   23	    # Puesto que esta es una función de cronómetro, devolver TRUE de manera
   24	    # que continúe siendo llamada
   25	    return gtk.TRUE
   26	
   27	class ProgressBar:
   28	    # Retrollamada que conmuta el dibujado del texto en el
   29	    # canal de la barra de progreso
   30	    def toggle_show_text(self, widget, data=None):
   31	        if widget.get_active():
   32	            self.pbar.set_text("some text")
   33	        else:
   34	            self.pbar.set_text("")
   35	
   36	    # Retrollamada que conmuta el modo de actividad de
   37	    # la barra de progreso
   38	    def toggle_activity_mode(self, widget, data=None):
   39	        if widget.get_active():
   40	            self.pbar.pulse()
   41	        else:
   42	            self.pbar.set_fraction(0.0)
   43	
   44	    # Retrollamada que conmuta la orientación de la barra de progreso
   45	    def toggle_orientation(self, widget, data=None):
   46	        if self.pbar.get_orientation() == gtk.PROGRESS_LEFT_TO_RIGHT:
   47	            self.pbar.set_orientation(gtk.PROGRESS_RIGHT_TO_LEFT)
   48	        elif self.pbar.get_orientation() == gtk.PROGRESS_RIGHT_TO_LEFT:
   49	            self.pbar.set_orientation(gtk.PROGRESS_LEFT_TO_RIGHT)
   50	
   51	    # Limpiamos la memoria reservada y eliminamos el temporizador
   52	    def destroy_progress(self, widget, data=None):
   53	        gtk.timeout_remove(self.timer)
   54	        self.timer = 0
   55	        gtk.main_quit()
   56	
   57	    def __init__(self):
   58	        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
   59	        self.window.set_resizable(gtk.TRUE)
   60	
   61	        self.window.connect("destroy", self.destroy_progress)
   62	        self.window.set_title("ProgressBar")
   63	        self.window.set_border_width(0)
   64	
   65	        vbox = gtk.VBox(gtk.FALSE, 5)
   66	        vbox.set_border_width(10)
   67	        self.window.add(vbox)
   68	        vbox.show()
   69	  
   70	        # Creamos un objeto de alineación centrador
   71	        align = gtk.Alignment(0.5, 0.5, 0, 0)
   72	        vbox.pack_start(align, gtk.FALSE, gtk.FALSE, 5)
   73	        align.show()
   74	
   75	        # Creamos la barra de progreso
   76	        self.pbar = gtk.ProgressBar()
   77	
   78	        align.add(self.pbar)
   79	        self.pbar.show()
   80	
   81	        # Añadimos una retrollamada temporizada para actualizar el valor de la barra
   82	        self.timer = gtk.timeout_add (100, progress_timeout, self)
   83	
   84	        separator = gtk.HSeparator()
   85	        vbox.pack_start(separator, gtk.FALSE, gtk.FALSE, 0)
   86	        separator.show()
   87	
   88	        # filas, columnas, homogéneas
   89	        table = gtk.Table(2, 2, gtk.FALSE)
   90	        vbox.pack_start(table, gtk.FALSE, gtk.TRUE, 0)
   91	        table.show()
   92	
   93	        # Añadir un botón de activación para mostrar o no el texto del canal
   94	        check = gtk.CheckButton("Show text")
   95	        table.attach(check, 0, 1, 0, 1,
   96	                     gtk.EXPAND | gtk.FILL, gtk.EXPAND | gtk.FILL,
   97	                     5, 5)
   98	        check.connect("clicked", self.toggle_show_text)
   99	        check.show()
  100	
  101	        # Añadir un botón de activación para conmutar el modo de actividad
  102	        self.activity_check = check = gtk.CheckButton("Activity mode")
  103	        table.attach(check, 0, 1, 1, 2,
  104	                     gtk.EXPAND | gtk.FILL, gtk.EXPAND | gtk.FILL,
  105	                     5, 5)
  106	        check.connect("clicked", self.toggle_activity_mode)
  107	        check.show()
  108	
  109	        # Añadir un botón de activación para conmutar de orientación
  110	        check = gtk.CheckButton("Right to Left")
  111	        table.attach(check, 0, 1, 2, 3,
  112	                     gtk.EXPAND | gtk.FILL, gtk.EXPAND | gtk.FILL,
  113	                     5, 5)
  114	        check.connect("clicked", self.toggle_orientation)
  115	        check.show()
  116	
  117	        # Añadir un botón para salir del programa
  118	        button = gtk.Button("close")
  119	        button.connect("clicked", self.destroy_progress)
  120	        vbox.pack_start(button, gtk.FALSE, gtk.FALSE, 0)
  121	
  122	        # Esto lo hace el botón por defecto
  123	        button.set_flags(gtk.CAN_DEFAULT)
  124	
  125	        # Esto hace que el botón tome el foco por defecto. Pulsando simplemente
  126	        # la tecla "Enter" se producirá la activación de este botón.
  127	        button.grab_default ()
  128	        button.show()
  129	
  130	        self.window.show()
  131	
  132	def main():
  133	    gtk.main()
  134	    return 0
  135	
  136	if __name__ == "__main__":
  137	    ProgressBar()
  138	    main()