4.3. Programa de Demostración de Empaquetamiento

Aqui está el código usado para crear la imágen de arriba. Esta bastante comentado asi que espero que no tengas ningún problema siguiendolo. Ejecútalo y juega con él.

    1	#!/usr/bin/env python
    2	
    3	# example packbox.py
    4	
    5	import gtk
    6	import sys, string
    7	
    8	# Helper function that makes a new hbox filled with button-labels. Arguments
    9	# for the variables we're interested are passed in to this function.  We do
   10	# not show the box, but do show everything inside.
   11	
   12	def make_box(homogeneous, spacing, expand, fill, padding):
   13	
   14	    # Create a new hbox with the appropriate homogeneous
   15	    # and spacing settings
   16	    box = gtk.HBox(homogeneous, spacing)
   17	
   18	    # Create a series of buttons with the appropriate settings
   19	    button = gtk.Button("box.pack")
   20	    box.pack_start(button, expand, fill, padding)
   21	    button.show()
   22	
   23	    button = gtk.Button("(button,")
   24	    box.pack_start(button, expand, fill, padding)
   25	    button.show()
   26	
   27	    # Create a button with the label depending on the value of
   28	    # expand.
   29	    if expand == gtk.TRUE:
   30	        button = gtk.Button("TRUE,")
   31	    else:
   32	        button = gtk.Button("FALSE,")
   33	
   34	    box.pack_start(button, expand, fill, padding)
   35	    button.show()
   36	
   37	    # This is the same as the button creation for "expand"
   38	    # above, but uses the shorthand form.
   39	    button = gtk.Button(("FALSE,", "TRUE,")[fill==gtk.TRUE])
   40	    box.pack_start(button, expand, fill, padding)
   41	    button.show()
   42	
   43	    padstr = "%d)" % padding
   44	
   45	    button = gtk.Button(padstr)
   46	    box.pack_start(button, expand, fill, padding)
   47	    button.show()
   48	    return box
   49	
   50	class PackBox1:
   51	    def delete_event(self, widget, event, data=None):
   52	        gtk.main_quit()
   53	        return gtk.FALSE
   54	
   55	    def __init__(self, which):
   56	
   57	        # Create our window
   58	        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
   59	
   60	        # You should always remember to connect the delete_event signal
   61	        # to the main window. This is very important for proper intuitive
   62	        # behavior
   63	        self.window.connect("delete_event", self.delete_event)
   64	        self.window.set_border_width(10)
   65	    
   66	        # We create a vertical box (vbox) to pack the horizontal boxes into.
   67	        # This allows us to stack the horizontal boxes filled with buttons one
   68	        # on top of the other in this vbox.
   69	        box1 = gtk.VBox(gtk.FALSE, 0)
   70	    
   71	        # which example to show. These correspond to the pictures above.
   72	        if which == 1:
   73	            # create a new label.
   74	            label = gtk.Label("HBox(FALSE, 0)")
   75		
   76	            # Align the label to the left side.  We'll discuss this method
   77	            # and others in the section on Widget Attributes.
   78	            label.set_alignment(0, 0)
   79	
   80	            # Pack the label into the vertical box (vbox box1).  Remember that 
   81	            # widgets added to a vbox will be packed one on top of the other in
   82	            # order.
   83	            box1.pack_start(label, gtk.FALSE, gtk.FALSE, 0)
   84		
   85	            # Show the label
   86	            label.show()
   87		
   88	            # Call our make box function - homogeneous = FALSE, spacing = 0,
   89	            # expand = FALSE, fill = FALSE, padding = 0
   90	            box2 = make_box(gtk.FALSE, 0, gtk.FALSE, gtk.FALSE, 0)
   91	            box1.pack_start(box2, gtk.FALSE, gtk.FALSE, 0)
   92	            box2.show()
   93	
   94	            # Call our make box function - homogeneous = FALSE, spacing = 0,
   95	            # expand = TRUE, fill = FALSE, padding = 0
   96	            box2 = make_box(gtk.FALSE, 0, gtk.TRUE, gtk.FALSE, 0)
   97	            box1.pack_start(box2, gtk.FALSE, gtk.FALSE, 0)
   98	            box2.show()
   99		
  100	            # Args are: homogeneous, spacing, expand, fill, padding
  101	            box2 = make_box(gtk.FALSE, 0, gtk.TRUE, gtk.TRUE, 0)
  102	            box1.pack_start(box2, gtk.FALSE, gtk.FALSE, 0)
  103	            box2.show()
  104		
  105	            # Creates a separator, we'll learn more about these later, 
  106	            # but they are quite simple.
  107	            separator = gtk.HSeparator()
  108		
  109	            # Pack the separator into the vbox. Remember each of these
  110	            # widgets is being packed into a vbox, so they'll be stacked
  111	            # vertically.
  112	            box1.pack_start(separator, gtk.FALSE, gtk.TRUE, 5)
  113	            separator.show()
  114		
  115	            # Create another new label, and show it.
  116	            label = gtk.Label("HBox(TRUE, 0)")
  117	            label.set_alignment(0, 0)
  118	            box1.pack_start(label, gtk.FALSE, gtk.FALSE, 0)
  119	            label.show()
  120		
  121	            # Args are: homogeneous, spacing, expand, fill, padding
  122	            box2 = make_box(gtk.TRUE, 0, gtk.TRUE, gtk.FALSE, 0)
  123	            box1.pack_start(box2, gtk.FALSE, gtk.FALSE, 0)
  124	            box2.show()
  125		
  126	            # Args are: homogeneous, spacing, expand, fill, padding
  127	            box2 = make_box(gtk.TRUE, 0, gtk.TRUE, gtk.TRUE, 0)
  128	            box1.pack_start(box2, gtk.FALSE, gtk.FALSE, 0)
  129	            box2.show()
  130		
  131	            # Another new separator.
  132	            separator = gtk.HSeparator()
  133	            # The last 3 arguments to pack_start are:
  134	            # expand, fill, padding.
  135	            box1.pack_start(separator, gtk.FALSE, gtk.TRUE, 5)
  136	            separator.show()
  137	        elif which == 2:
  138	            # Create a new label, remember box1 is a vbox as created 
  139	            # near the beginning of __init__()
  140	            label = gtk.Label("HBox(FALSE, 10)")
  141	            label.set_alignment( 0, 0)
  142	            box1.pack_start(label, gtk.FALSE, gtk.FALSE, 0)
  143	            label.show()
  144		
  145	            # Args are: homogeneous, spacing, expand, fill, padding
  146	            box2 = make_box(gtk.FALSE, 10, gtk.TRUE, gtk.FALSE, 0)
  147	            box1.pack_start(box2, gtk.FALSE, gtk.FALSE, 0)
  148	            box2.show()
  149		
  150	            # Args are: homogeneous, spacing, expand, fill, padding
  151	            box2 = make_box(gtk.FALSE, 10, gtk.TRUE, gtk.TRUE, 0)
  152	            box1.pack_start(box2, gtk.FALSE, gtk.FALSE, 0)
  153	            box2.show()
  154		
  155	            separator = gtk.HSeparator()
  156	            # The last 3 arguments to pack_start are:
  157	            # expand, fill, padding.
  158	            box1.pack_start(separator, gtk.FALSE, gtk.TRUE, 5)
  159	            separator.show()
  160		
  161	            label = gtk.Label("HBox(FALSE, 0)")
  162	            label.set_alignment(0, 0)
  163	            box1.pack_start(label, gtk.FALSE, gtk.FALSE, 0)
  164	            label.show()
  165		
  166	            # Args are: homogeneous, spacing, expand, fill, padding
  167	            box2 = make_box(gtk.FALSE, 0, gtk.TRUE, gtk.FALSE, 10)
  168	            box1.pack_start(box2, gtk.FALSE, gtk.FALSE, 0)
  169	            box2.show()
  170		
  171	            # Args are: homogeneous, spacing, expand, fill, padding
  172	            box2 = make_box(gtk.FALSE, 0, gtk.TRUE, gtk.TRUE, 10)
  173	            box1.pack_start(box2, gtk.FALSE, gtk.FALSE, 0)
  174	            box2.show()
  175		
  176	            separator = gtk.HSeparator()
  177	            # The last 3 arguments to pack_start are:
  178	            # expand, fill, padding.
  179	            box1.pack_start(separator, gtk.FALSE, gtk.TRUE, 5)
  180	            separator.show()
  181	
  182	        elif which == 3:
  183	
  184	            # This demonstrates the ability to use pack_end() to
  185	            # right justify widgets. First, we create a new box as before.
  186	            box2 = make_box(gtk.FALSE, 0, gtk.FALSE, gtk.FALSE, 0)
  187	
  188	            # Create the label that will be put at the end.
  189	            label = gtk.Label("end")
  190	            # Pack it using pack_end(), so it is put on the right
  191	            # side of the hbox created in the make_box() call.
  192	            box2.pack_end(label, gtk.FALSE, gtk.FALSE, 0)
  193	            # Show the label.
  194	            label.show()
  195		
  196	            # Pack box2 into box1
  197	            box1.pack_start(box2, gtk.FALSE, gtk.FALSE, 0)
  198	            box2.show()
  199		
  200	            # A separator for the bottom.
  201	            separator = gtk.HSeparator()
  202	            
  203	            # This explicitly sets the separator to 400 pixels wide by 5
  204	            # pixels high. This is so the hbox we created will also be 400
  205	            # pixels wide, and the "end" label will be separated from the
  206	            # other labels in the hbox. Otherwise, all the widgets in the
  207	            # hbox would be packed as close together as possible.
  208	            separator.set_usize(400, 5)
  209	            # pack the separator into the vbox (box1) created near the start 
  210	            # of __init__()
  211	            box1.pack_start(separator, gtk.FALSE, gtk.TRUE, 5)
  212	            separator.show()
  213	    
  214	        # Create another new hbox.. remember we can use as many as we need!
  215	        quitbox = gtk.HBox(gtk.FALSE, 0)
  216	    
  217	        # Our quit button.
  218	        button = gtk.Button("Quit")
  219	    
  220	        # Setup the signal to terminate the program when the button is clicked
  221	        button.connect_object("clicked", gtk.mainquit, self.window)
  222	        # Pack the button into the quitbox.
  223	        # The last 3 arguments to pack_start are:
  224	        # expand, fill, padding.
  225	        quitbox.pack_start(button, gtk.TRUE, gtk.FALSE, 0)
  226	        # pack the quitbox into the vbox (box1)
  227	        box1.pack_start(quitbox, gtk.FALSE, gtk.FALSE, 0)
  228	    
  229	        # Pack the vbox (box1) which now contains all our widgets, into the
  230	        # main window.
  231	        self.window.add(box1)
  232	    
  233	        # And show everything left
  234	        button.show()
  235	        quitbox.show()
  236	    
  237	        box1.show()
  238	        # Showing the window last so everything pops up at once.
  239	        self.window.show()
  240	
  241	def main():
  242	    # And of course, our main loop.
  243	    gtk.main()
  244	    # Control returns here when main_quit() is called
  245	    return 0         
  246	
  247	if __name__ =="__main__":
  248	    if len(sys.argv) != 2:
  249	        sys.stderr.write("usage: packbox.py num, where num is 1, 2, or 3.\n")
  250	        sys.exit(1)
  251	    PackBox1(string.atoi(sys.argv[1]))
  252	    main()

El pequeño tour por el código packbox.py empieza por las lineas 12-48 que definen una función auxiliar que crea una caja horizontal y la rellena con botones según los parámetros específicados. Devuelve una referencia a la caja horizontal.

Las lineas 55-239 definen el método de inicialización __init__() de la clase PackBox1 que crea una ventana y una caja vertical dentro de ella que se rellena con una configuración de controles dependiendo del argumento que se le pase. Si se le pasa un 1, las lineas 73-136 crean una ventana mostrando las cinco únicas posibilidades que hay cuando variamos los parámetros homogeneous, expand y fill. Si se le pasa un 2, las lineas 138-180 crean una ventana mostrando las diferentes combinaciones de fill con spacing y padding. Finalmente, si le pasamos un 3, las lineas 186-212 crean una ventana mostrando el uso del método pack_start() para justificar los botones a la izquierda y el método pack_end() para justificar una etiqueta a la derecha. Las lineas 215-235 crean una caja horizontal que contiene un botón que se empaqueta dentro de la caja vertical. La señal 'clicked' del botón está conectada a la función PyGTK main_quit() para terminar el programa.

Las lineas 248-250 comprueba los argumentos de la linea de comandos y terminan el programa usando la función sys.exit() si no hay exactamente un argumento. La linea 251 crea una instancia de PackBox1. La linea 252 llama a la función main() para empezar el bucle de procesamiento de eventos GTK.

En este programa de ejemplo, las referencias a los controles (excepto a la ventana) no se guardan en los atributos de instancia del objeto porque no se necesitan después.