8.5. Ejemplo de Control de Rango

El programa de ejemplo (rangewidgets.py) es una versión modificada del test "controles de rango" de testgtk.py. Básicamente muestra una ventana con tres controles de rango todos conectados al mismo ajuste, y un par de controles para ajustar algunos de los parámetros mencionados más arriba y en la sección de ajustes, por lo que puedes ver como afectan a la manera en la que estos controles funcionan 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	# example rangewidgets.py
    4	
    5	import gtk
    6	
    7	# Convenience functions
    8	
    9	def make_menu_item(name, callback, data=None):
   10	    item = gtk.MenuItem(name)
   11	    item.connect("activate", callback, data)
   12	    item.show()
   13	    return item
   14	
   15	def scale_set_default_values(scale):
   16	    scale.set_update_policy(gtk.UPDATE_CONTINUOUS)
   17	    scale.set_digits(1)
   18	    scale.set_value_pos(gtk.POS_TOP)
   19	    scale.set_draw_value(gtk.TRUE)
   20	
   21	class RangeWidgets:
   22	    def cb_pos_menu_select(self, item, pos):
   23	        # Set the value position on both scale widgets
   24	        self.hscale.set_value_pos(pos)
   25	        self.vscale.set_value_pos(pos)
   26	
   27	    def cb_update_menu_select(self, item, policy):
   28	        # Set the update policy for both scale widgets
   29	        self.hscale.set_update_policy(policy)
   30	        self.vscale.set_update_policy(policy)
   31	
   32	    def cb_digits_scale(self, adj):
   33	        # Set the number of decimal places to which adj->value is rounded
   34	        self.hscale.set_digits(adj.value)
   35	        self.vscale.set_digits(adj.value)
   36	
   37	    def cb_page_size(self, get, set):
   38	        # Set the page size and page increment size of the sample
   39	        # adjustment to the value specified by the "Page Size" scale
   40	        set.page_size = get.value
   41	        set.page_incr = get.value
   42	        # Now emit the "changed" signal to reconfigure all the widgets that
   43	        # are attached to this adjustment
   44	        set.emit("changed")
   45	
   46	    def cb_draw_value(self, button):
   47	        # Turn the value display on the scale widgets off or on depending
   48	        # on the state of the checkbutton
   49	        self.hscale.set_draw_value(button.get_active())
   50	        self.vscale.set_draw_value(button.get_active())  
   51	
   52	    # makes the sample window
   53	
   54	    def __init__(self):
   55	        # Standard window-creating stuff
   56	        self.window = gtk.Window (gtk.WINDOW_TOPLEVEL)
   57	        self.window.connect("destroy", gtk.mainquit)
   58	        self.window.set_title("range controls")
   59	
   60	        box1 = gtk.VBox(gtk.FALSE, 0)
   61	        self.window.add(box1)
   62	        box1.show()
   63	
   64	        box2 = gtk.HBox(gtk.FALSE, 10)
   65	        box2.set_border_width(10)
   66	        box1.pack_start(box2, gtk.TRUE, gtk.TRUE, 0)
   67	        box2.show()
   68	
   69	        # value, lower, upper, step_increment, page_increment, page_size
   70	        # Note that the page_size value only makes a difference for
   71	        # scrollbar widgets, and the highest value you'll get is actually
   72	        # (upper - page_size).
   73	        adj1 = gtk.Adjustment(0.0, 0.0, 101.0, 0.1, 1.0, 1.0)
   74	  
   75	        self.vscale = gtk.VScale(adj1)
   76	        scale_set_default_values(self.vscale)
   77	        box2.pack_start(self.vscale, gtk.TRUE, gtk.TRUE, 0)
   78	        self.vscale.show()
   79	
   80	        box3 = gtk.VBox(gtk.FALSE, 10)
   81	        box2.pack_start(box3, gtk.TRUE, gtk.TRUE, 0)
   82	        box3.show()
   83	
   84	        # Reuse the same adjustment
   85	        self.hscale = gtk.HScale(adj1)
   86	        self.hscale.set_size_request(200, 30)
   87	        scale_set_default_values(self.hscale)
   88	        box3.pack_start(self.hscale, gtk.TRUE, gtk.TRUE, 0)
   89	        self.hscale.show()
   90	
   91	        # Reuse the same adjustment again
   92	        scrollbar = gtk.HScrollbar(adj1)
   93	        # Notice how this causes the scales to always be updated
   94	        # continuously when the scrollbar is moved
   95	        scrollbar.set_update_policy(gtk.UPDATE_CONTINUOUS)
   96	        box3.pack_start(scrollbar, gtk.TRUE, gtk.TRUE, 0)
   97	        scrollbar.show()
   98	
   99	        box2 = gtk.HBox(gtk.FALSE, 10)
  100	        box2.set_border_width(10)
  101	        box1.pack_start(box2, gtk.TRUE, gtk.TRUE, 0)
  102	        box2.show()
  103	
  104	        # A checkbutton to control whether the value is displayed or not
  105	        button = gtk.CheckButton("Display value on scale widgets")
  106	        button.set_active(gtk.TRUE)
  107	        button.connect("toggled", self.cb_draw_value)
  108	        box2.pack_start(button, gtk.TRUE, gtk.TRUE, 0)
  109	        button.show()
  110	  
  111	        box2 = gtk.HBox(gtk.FALSE, 10)
  112	        box2.set_border_width(10)
  113	
  114	        # An option menu to change the position of the value
  115	        label = gtk.Label("Scale Value Position:")
  116	        box2.pack_start(label, gtk.FALSE, gtk.FALSE, 0)
  117	        label.show()
  118	  
  119	        opt = gtk.OptionMenu()
  120	        menu = gtk.Menu()
  121	
  122	        item = make_menu_item ("Top", self.cb_pos_menu_select, gtk.POS_TOP)
  123	        menu.append(item)
  124	  
  125	        item = make_menu_item ("Bottom", self.cb_pos_menu_select,
  126	                               gtk.POS_BOTTOM)
  127	        menu.append(item)
  128	  
  129	        item = make_menu_item ("Left", self.cb_pos_menu_select, gtk.POS_LEFT)
  130	        menu.append(item)
  131	  
  132	        item = make_menu_item ("Right", self.cb_pos_menu_select, gtk.POS_RIGHT)
  133	        menu.append(item)
  134	  
  135	        opt.set_menu(menu)
  136	        box2.pack_start(opt, gtk.TRUE, gtk.TRUE, 0)
  137	        opt.show()
  138	
  139	        box1.pack_start(box2, gtk.TRUE, gtk.TRUE, 0)
  140	        box2.show()
  141	
  142	        box2 = gtk.HBox(gtk.FALSE, 10)
  143	        box2.set_border_width(10)
  144	
  145	        # Yet another option menu, this time for the update policy of the
  146	        # scale widgets
  147	        label = gtk.Label("Scale Update Policy:")
  148	        box2.pack_start(label, gtk.FALSE, gtk.FALSE, 0)
  149	        label.show()
  150	  
  151	        opt = gtk.OptionMenu()
  152	        menu = gtk.Menu()
  153	  
  154	        item = make_menu_item("Continuous", self.cb_update_menu_select,
  155	                              gtk.UPDATE_CONTINUOUS)
  156	        menu.append(item)
  157	  
  158	        item = make_menu_item ("Discontinuous", self.cb_update_menu_select,
  159	                               gtk.UPDATE_DISCONTINUOUS)
  160	        menu.append(item)
  161	  
  162	        item = make_menu_item ("Delayed", self.cb_update_menu_select,
  163	                               gtk.UPDATE_DELAYED)
  164	        menu.append(item)
  165	  
  166	        opt.set_menu(menu)
  167	        box2.pack_start(opt, gtk.TRUE, gtk.TRUE, 0)
  168	        opt.show()
  169	  
  170	        box1.pack_start(box2, gtk.TRUE, gtk.TRUE, 0)
  171	        box2.show()
  172	
  173	        box2 = gtk.HBox(gtk.FALSE, 10)
  174	        box2.set_border_width(10)
  175	  
  176	        # An HScale widget for adjusting the number of digits on the
  177	        # sample scales.
  178	        label = gtk.Label("Scale Digits:")
  179	        box2.pack_start(label, gtk.FALSE, gtk.FALSE, 0)
  180	        label.show()
  181	
  182	        adj2 = gtk.Adjustment(1.0, 0.0, 5.0, 1.0, 1.0, 0.0)
  183	        adj2.connect("value_changed", self.cb_digits_scale)
  184	        scale = gtk.HScale(adj2)
  185	        scale.set_digits(0)
  186	        box2.pack_start(scale, gtk.TRUE, gtk.TRUE, 0)
  187	        scale.show()
  188	
  189	        box1.pack_start(box2, gtk.TRUE, gtk.TRUE, 0)
  190	        box2.show()
  191	  
  192	        box2 = gtk.HBox(gtk.FALSE, 10)
  193	        box2.set_border_width(10)
  194	  
  195	        # And, one last HScale widget for adjusting the page size of the
  196	        # scrollbar.
  197	        label = gtk.Label("Scrollbar Page Size:")
  198	        box2.pack_start(label, gtk.FALSE, gtk.FALSE, 0)
  199	        label.show()
  200	
  201	        adj2 = gtk.Adjustment(1.0, 1.0, 101.0, 1.0, 1.0, 0.0)
  202	        adj2.connect("value_changed", self.cb_page_size, adj1)
  203	        scale = gtk.HScale(adj2)
  204	        scale.set_digits(0)
  205	        box2.pack_start(scale, gtk.TRUE, gtk.TRUE, 0)
  206	        scale.show()
  207	
  208	        box1.pack_start(box2, gtk.TRUE, gtk.TRUE, 0)
  209	        box2.show()
  210	
  211	        separator = gtk.HSeparator()
  212	        box1.pack_start(separator, gtk.FALSE, gtk.TRUE, 0)
  213	        separator.show()
  214	
  215	        box2 = gtk.VBox(gtk.FALSE, 10)
  216	        box2.set_border_width(10)
  217	        box1.pack_start(box2, gtk.FALSE, gtk.TRUE, 0)
  218	        box2.show()
  219	
  220	        button = gtk.Button("Quit")
  221	        button.connect_object("clicked", gtk.mainquit, self.window)
  222	        box2.pack_start(button, gtk.TRUE, gtk.TRUE, 0)
  223	        button.set_flags(gtk.CAN_DEFAULT)
  224	        button.grab_default()
  225	        button.show()
  226	        self.window.show()
  227	
  228	def main():
  229	    gtk.main()
  230	    return 0            
  231	
  232	if __name__ == "__main__":
  233	    RangeWidgets()
  234	    main()

Notarás que el programa no llama al método connect() para el evento "delete_event", si sólo con la señal destroy. Esto seguirá realizando la acción deseada porque un evento "delete_event" sin tratar resultará en una señal "destroy" mandada a la ventana.