8.5. Ejemplo de Control de Rango

El programa de ejemplo (rangewidgets.py) muestra una ventana con tres controles de rango todos conectados al mismo ajuste, y un par de controles para modificar algunos de los parámetros mencionados más arriba y en la sección de ajustes, por lo que se puede ver cómo afectan a la manera en la que estos controles se comportan para el usuario. La figura Figura 8.1, “Ejemplo de Controles de Rango” muestra el resultado de ejecutar el programa:

Figura 8.1. Ejemplo de Controles de Rango

Ejemplo de Controles de Rango

El código fuente de rangewidgets.py es:

    1	#!/usr/bin/env python
    2	
    3	# ejemplo rangewidgets.py
    4	
    5	import pygtk
    6	pygtk.require('2.0')
    7	import gtk
    8	
    9	# Funciones auxiliares
   10	
   11	def make_menu_item(name, callback, data=None):
   12	    item = gtk.MenuItem(name)
   13	    item.connect("activate", callback, data)
   14	    item.show()
   15	    return item
   16	
   17	def scale_set_default_values(scale):
   18	    scale.set_update_policy(gtk.UPDATE_CONTINUOUS)
   19	    scale.set_digits(1)
   20	    scale.set_value_pos(gtk.POS_TOP)
   21	    scale.set_draw_value(gtk.TRUE)
   22	
   23	class RangeWidgets:
   24	    def cb_pos_menu_select(self, item, pos):
   25	        # Fijar la posición del valor para ambos ajustes
   26	        self.hscale.set_value_pos(pos)
   27	        self.vscale.set_value_pos(pos)
   28	
   29	    def cb_update_menu_select(self, item, policy):
   30	        # Establecer la política de actualización para ambos controles
   31	        self.hscale.set_update_policy(policy)
   32	        self.vscale.set_update_policy(policy)
   33	
   34	    def cb_digits_scale(self, adj):
   35	        # Fijar el número de posiciones decimales a las que se ajusta el valor
   36	        self.hscale.set_digits(adj.value)
   37	        self.vscale.set_digits(adj.value)
   38	
   39	    def cb_page_size(self, get, set):
   40	        # Fijar el valor del tamaño de página y de su incremento
   41	        # para el ajuste al valor especificado por la escala "Page Size"
   42	        set.page_size = get.value
   43	        set.page_incr = get.value
   44	        # Ahora emitir la señal "changed" para reconfigurar todos los controles
   45	        # que están ligados a este ajuste
   46	        set.emit("changed")
   47	
   48	    def cb_draw_value(self, button):
   49	        # Activar o desactivar la representación del valor en función del
   50	        # estado del botón de activación
   51	        self.hscale.set_draw_value(button.get_active())
   52	        self.vscale.set_draw_value(button.get_active())  
   53	
   54	    # crea la ventana de ejemplo
   55	
   56	    def __init__(self):
   57	        # Creación de la ventana principal
   58	        self.window = gtk.Window (gtk.WINDOW_TOPLEVEL)
   59	        self.window.connect("destroy", lambda w: gtk.main_quit())
   60	        self.window.set_title("range controls")
   61	
   62	        box1 = gtk.VBox(gtk.FALSE, 0)
   63	        self.window.add(box1)
   64	        box1.show()
   65	
   66	        box2 = gtk.HBox(gtk.FALSE, 10)
   67	        box2.set_border_width(10)
   68	        box1.pack_start(box2, gtk.TRUE, gtk.TRUE, 0)
   69	        box2.show()
   70	
   71	        # value, lower, upper, step_increment, page_increment, page_size
   72	        # Obsérvese que el valor page_size solamente es significativo
   73	        # para controles de barra de desplazamiento y que el valor más alto posible es
   74	        # (upper - page_size).
   75	        adj1 = gtk.Adjustment(0.0, 0.0, 101.0, 0.1, 1.0, 1.0)
   76	  
   77	        self.vscale = gtk.VScale(adj1)
   78	        scale_set_default_values(self.vscale)
   79	        box2.pack_start(self.vscale, gtk.TRUE, gtk.TRUE, 0)
   80	        self.vscale.show()
   81	
   82	        box3 = gtk.VBox(gtk.FALSE, 10)
   83	        box2.pack_start(box3, gtk.TRUE, gtk.TRUE, 0)
   84	        box3.show()
   85	
   86	        # Reutilizamos el mismo ajuste
   87	        self.hscale = gtk.HScale(adj1)
   88	        self.hscale.set_size_request(200, 30)
   89	        scale_set_default_values(self.hscale)
   90	        box3.pack_start(self.hscale, gtk.TRUE, gtk.TRUE, 0)
   91	        self.hscale.show()
   92	
   93	        # Reutilizamos el mismo ajuste otra vez
   94	        scrollbar = gtk.HScrollbar(adj1)
   95	        # Obsérvese como esto hace que las escalas se actualicen
   96	        # continuamente cuando se mueve la barra de desplazamiento
   97	        scrollbar.set_update_policy(gtk.UPDATE_CONTINUOUS)
   98	        box3.pack_start(scrollbar, gtk.TRUE, gtk.TRUE, 0)
   99	        scrollbar.show()
  100	
  101	        box2 = gtk.HBox(gtk.FALSE, 10)
  102	        box2.set_border_width(10)
  103	        box1.pack_start(box2, gtk.TRUE, gtk.TRUE, 0)
  104	        box2.show()
  105	
  106	        # Un botón de activación para definir se se muestra el valor o no
  107	        button = gtk.CheckButton("Display value on scale widgets")
  108	        button.set_active(gtk.TRUE)
  109	        button.connect("toggled", self.cb_draw_value)
  110	        box2.pack_start(button, gtk.TRUE, gtk.TRUE, 0)
  111	        button.show()
  112	  
  113	        box2 = gtk.HBox(gtk.FALSE, 10)
  114	        box2.set_border_width(10)
  115	
  116	        # Un menú de opciones para cambiar la posición del valor
  117	        label = gtk.Label("Scale Value Position:")
  118	        box2.pack_start(label, gtk.FALSE, gtk.FALSE, 0)
  119	        label.show()
  120	  
  121	        opt = gtk.OptionMenu()
  122	        menu = gtk.Menu()
  123	
  124	        item = make_menu_item ("Top", self.cb_pos_menu_select, gtk.POS_TOP)
  125	        menu.append(item)
  126	  
  127	        item = make_menu_item ("Bottom", self.cb_pos_menu_select,
  128	                               gtk.POS_BOTTOM)
  129	        menu.append(item)
  130	  
  131	        item = make_menu_item ("Left", self.cb_pos_menu_select, gtk.POS_LEFT)
  132	        menu.append(item)
  133	  
  134	        item = make_menu_item ("Right", self.cb_pos_menu_select, gtk.POS_RIGHT)
  135	        menu.append(item)
  136	  
  137	        opt.set_menu(menu)
  138	        box2.pack_start(opt, gtk.TRUE, gtk.TRUE, 0)
  139	        opt.show()
  140	
  141	        box1.pack_start(box2, gtk.TRUE, gtk.TRUE, 0)
  142	        box2.show()
  143	
  144	        box2 = gtk.HBox(gtk.FALSE, 10)
  145	        box2.set_border_width(10)
  146	
  147	        # Otro menú de opciones más, esta vez para la política de actualización
  148	        # de los controles de escala
  149	        label = gtk.Label("Scale Update Policy:")
  150	        box2.pack_start(label, gtk.FALSE, gtk.FALSE, 0)
  151	        label.show()
  152	  
  153	        opt = gtk.OptionMenu()
  154	        menu = gtk.Menu()
  155	  
  156	        item = make_menu_item("Continuous", self.cb_update_menu_select,
  157	                              gtk.UPDATE_CONTINUOUS)
  158	        menu.append(item)
  159	  
  160	        item = make_menu_item ("Discontinuous", self.cb_update_menu_select,
  161	                               gtk.UPDATE_DISCONTINUOUS)
  162	        menu.append(item)
  163	  
  164	        item = make_menu_item ("Delayed", self.cb_update_menu_select,
  165	                               gtk.UPDATE_DELAYED)
  166	        menu.append(item)
  167	  
  168	        opt.set_menu(menu)
  169	        box2.pack_start(opt, gtk.TRUE, gtk.TRUE, 0)
  170	        opt.show()
  171	  
  172	        box1.pack_start(box2, gtk.TRUE, gtk.TRUE, 0)
  173	        box2.show()
  174	
  175	        box2 = gtk.HBox(gtk.FALSE, 10)
  176	        box2.set_border_width(10)
  177	  
  178	        # Un control HScale para ajustar el número de dígitos en las escalas
  179	        # de ejemplo
  180	        label = gtk.Label("Scale Digits:")
  181	        box2.pack_start(label, gtk.FALSE, gtk.FALSE, 0)
  182	        label.show()
  183	
  184	        adj2 = gtk.Adjustment(1.0, 0.0, 5.0, 1.0, 1.0, 0.0)
  185	        adj2.connect("value_changed", self.cb_digits_scale)
  186	        scale = gtk.HScale(adj2)
  187	        scale.set_digits(0)
  188	        box2.pack_start(scale, gtk.TRUE, gtk.TRUE, 0)
  189	        scale.show()
  190	
  191	        box1.pack_start(box2, gtk.TRUE, gtk.TRUE, 0)
  192	        box2.show()
  193	  
  194	        box2 = gtk.HBox(gtk.FALSE, 10)
  195	        box2.set_border_width(10)
  196	  
  197	        # Y un último control HScale para ajustar el tamaño de página
  198	        # de la barra de desplazamiento.
  199	        label = gtk.Label("Scrollbar Page Size:")
  200	        box2.pack_start(label, gtk.FALSE, gtk.FALSE, 0)
  201	        label.show()
  202	
  203	        adj2 = gtk.Adjustment(1.0, 1.0, 101.0, 1.0, 1.0, 0.0)
  204	        adj2.connect("value_changed", self.cb_page_size, adj1)
  205	        scale = gtk.HScale(adj2)
  206	        scale.set_digits(0)
  207	        box2.pack_start(scale, gtk.TRUE, gtk.TRUE, 0)
  208	        scale.show()
  209	
  210	        box1.pack_start(box2, gtk.TRUE, gtk.TRUE, 0)
  211	        box2.show()
  212	
  213	        separator = gtk.HSeparator()
  214	        box1.pack_start(separator, gtk.FALSE, gtk.TRUE, 0)
  215	        separator.show()
  216	
  217	        box2 = gtk.VBox(gtk.FALSE, 10)
  218	        box2.set_border_width(10)
  219	        box1.pack_start(box2, gtk.FALSE, gtk.TRUE, 0)
  220	        box2.show()
  221	
  222	        button = gtk.Button("Quit")
  223	        button.connect("clicked", lambda w: gtk.main_quit())
  224	        box2.pack_start(button, gtk.TRUE, gtk.TRUE, 0)
  225	        button.set_flags(gtk.CAN_DEFAULT)
  226	        button.grab_default()
  227	        button.show()
  228	        self.window.show()
  229	
  230	def main():
  231	    gtk.main()
  232	    return 0            
  233	
  234	if __name__ == "__main__":
  235	    RangeWidgets()
  236	    main()

Se debe advertir que el programa no llama al método connect() para el evento "delete_event", sino solamente a la señal "destroy". Esto seguirá realizando la acción deseada, puesto que un evento "delete_event" sin tratar resultará en una señal "destroy" enviada a la ventana.