10.4. Contenedor de Disposición (Layout)

El contenedor Layout (Disposición) es similar al contenedor Fixed (Fijo) excepto en que implementa un área de desplazamiento infinita (donde infinito es menor que 2^32). El sistema de ventanas X tiene una limitación que hace uqe las ventanas sólo puedan tener 32767 píxeles de ancho o alto. El contenedor Layout soluciona esta limitación haciendo algunos trucos exóticos mediante el uso de gravedad de ventana y de bit, para que se tenga un desplazamiento suave incluso cuando se tienen muchos controles en el área de desplazamiento.

Un contenedor Layout se crea con:

  layout = gtk.Layout(hadjustment=None, vadjustment=None)

Como se puede ver, se puede especificar opcionalmente los objetos Adjustment que el control Layout usará para su desplazamiento. Si no se especifican los objetos Adjustment, se crearán unos nuevos.

Se pueden añadir y mover controles en el contenedor Layout usando los dos métodos siguientes:

  layout.put(child_widget, x, y)

  layout.move(child_widget, x, y)

El tamaño del contenedor Layout se puede establecer y consultar usando los siguientes métodos:

  layout.set_size(width, height)

  size = layout.get_size()

Los últimos cuatro métodos para los controles Layout widgets son para manipular los controles de ajuste horizontal y vertical:

  hadj = layout.get_hadjustment()

  vadj = layout.get_vadjustment()

  layout.set_hadjustment(adjustment)

  layout.set_vadjustment(adjustment)

El programa de ejemplo layout.py crea tres botones y los pone en un control disposición. Cuando se hace clic en un botón, se mueve a una posición aleatoria en el control disposición. La figura Figura 10.3, “Ejemplo de Disposición” ilustra la ventana inicial del programa:

Figura 10.3. Ejemplo de Disposición

Ejemplo de Disposición

El código fuente de layout.py es:

    1	#!/usr/bin/env python
    2	
    3	# ejemplo layout.py
    4	
    5	import pygtk
    6	pygtk.require('2.0')
    7	import gtk
    8	import random
    9	
   10	class LayoutExample:
   11	    def WindowDeleteEvent(self, widget, event):
   12	        # devolvemos false para que se destruya la ventana
   13	        return gtk.FALSE
   14	
   15	    def WindowDestroy(self, widget, *data):
   16	        # salimos del bucle principal
   17	        gtk.main_quit()
   18	
   19	    def ButtonClicked(self, button):
   20	        # movemos el botón
   21	        self.layout.move(button, random.randint(0,500),
   22	                         random.randint(0,500))
   23	
   24	    def __init__(self):
   25	        # creamos la ventana principal
   26	        window = gtk.Window(gtk.WINDOW_TOPLEVEL)
   27	        window.set_title("Layout Example")
   28	        window.set_default_size(300, 300)
   29	        window.connect("delete-event", self.WindowDeleteEvent)
   30	        window.connect("destroy", self.WindowDestroy)
   31	        # creamos la tabla y la empaquetamos en la ventana
   32	        table = gtk.Table(2, 2, gtk.FALSE)
   33	        window.add(table)
   34	        # creamos el control disposición y lo empaquetamos en la tabla
   35	        self.layout = gtk.Layout(None, None)
   36	        self.layout.set_size(600, 600)
   37	        table.attach(self.layout, 0, 1, 0, 1, gtk.FILL|gtk.EXPAND,
   38	                     gtk.FILL|gtk.EXPAND, 0, 0)
   39	        # creamos las barras de desplazamiento y las empaquetamos también
   40	        vScrollbar = gtk.VScrollbar(None)
   41	        table.attach(vScrollbar, 1, 2, 0, 1, gtk.FILL|gtk.SHRINK,
   42	                     gtk.FILL|gtk.SHRINK, 0, 0)
   43	        hScrollbar = gtk.HScrollbar(None)
   44	        table.attach(hScrollbar, 0, 1, 1, 2, gtk.FILL|gtk.SHRINK,
   45	                     gtk.FILL|gtk.SHRINK, 0, 0)	
   46	        # indicamos a las barras de desp. que usen el ajuste del control disposición
   47	        vAdjust = self.layout.get_vadjustment()
   48	        vScrollbar.set_adjustment(vAdjust)
   49	        hAdjust = self.layout.get_hadjustment()
   50	        hScrollbar.set_adjustment(hAdjust)
   51	        # creamos 3 botones ylos ponemos en el control disposición
   52	        button = gtk.Button("Press Me")
   53	        button.connect("clicked", self.ButtonClicked)
   54	        self.layout.put(button, 0, 0)
   55	        button = gtk.Button("Press Me")
   56	        button.connect("clicked", self.ButtonClicked)
   57	        self.layout.put(button, 100, 0)
   58	        button = gtk.Button("Press Me")
   59	        button.connect("clicked", self.ButtonClicked)
   60	        self.layout.put(button, 200, 0)
   61	        # mostramos todos los controles
   62	        window.show_all()
   63	
   64	def main():
   65	    # entramos en el bucle principal
   66	    gtk.main()
   67	    return 0
   68	
   69	if __name__ == "__main__":
   70	    LayoutExample()
   71	    main()