Informatica Grafica
C A P I T U L O11 El Pack

Los geometry manager son los encargados de situar los widgets en la pantalla. Existen numerosos geometry manager, y puede ser usado cualquiera, en cualquier parte de la aplicación, pero este trabajo utilizará el geometry manager denominado pack. Tk, además del pack, provee otro geometry manager denominado place.

Un geometry manager, básicamente, utiliza un widget como padre y coloca numerosos widgets hijos, también denominados esclavos, dentro de él. El padre es generalmente una frame, pero esto no es estrictamente necesario, pudiendo ser otro widget cualquiera.

Los ejemplo siguientes pueden ser ejecutados desde la consola de Tk.

Efectos de los diferentes parámetros del pack

Ejemplo 11-1.
# Crea una ventana negra
. config -bg black
# Crea y situa dos frames una blanca y otra gris
frame .uno -width 40 -height 40 -bg white
frame .dos -width 100 -height 100 -bg grey50
pack .uno .dos -side top


En este ejemplo, se ha coloreado de negro la ventana principal con el comando config, y dentro de ella se han situado dos frames; una de ellas blanca y la otra de color gris. a continuación se han "empaquetado" las dos con el pack, ordenándole que las sitúe en top; es decir en la parte superior de la frame padre; o mejor dicho, que las sitúe lo más arriba posible. El resultado es este:

 

Hay que hacer notar, la importancia del orden es importante, pero no el de creación, sino el de empaquetado

Ejemplo 11-2.
frame .uno -bg white
frame .dos -width 100 -height 50 -bg grey50
# Crea una fila de botones.
foreach b { boton1 boton2 boton3 } {
button .uno.$b -text $b
pack .uno.$b -side left
}
pack .uno .dos -side top


Este ejemplo es similar al anterior, con la diferencia de que dentro de la frame .uno se han colocado tres botones que se han empaquetado uno al lado del otro hacia la izquierda, con lo que el primero en empaquetarse se colocará todo lo que pueda a la izquierda, el siguiente un poco menos porque se lo impide el primero, y el tercero menos aún. El resultado es el siguiente:

Ejemplo 11-3.
frame .uno -bg white
frame .dos -width 100 -height 50 -bg grey50
# Crea una fila de botones.
foreach b { boton1 boton2 } {
button .uno.$b -text $b
pack .uno.$b -side left
}
# Crea otra frame para añadir más botones.
frame .uno.dercha
foreach b { boton3 boton4 } {
button .uno.dercha.$b -text $b
pack .uno.dercha.$b -side bottom
}
pack .uno.dercha -side right
pack .uno .dos -side top

Dentro de la frame .uno, se ha creado otra frame denominada .uno.dercha, que se va a situar a la derecha de la frame .uno (-side right); y dentro de ella se sitúan dos botones, uno sobre el otro, pero empezando a empaquetarse desde abajo (-side bottom). El resultado es el siguiente:

 

El modelo de cavidad (Cavity Model)

El algoritmo de empaquetado está basado en el modelo de cavidad (cavity model) para el espacio disponible dentro de la frame. La principal regla de este modelo es que un widget ocupa un espacio completo en la frame. Esto se ve más claro con el ejemplo siguiente:

Ejemplo 11-4.
# Se crean dos frames y se empaquetan en la parte inferior de la frame principal
frame .uno -width 100 -height 50 -bg grey50
frame .dos -width 40 -height 40 -bg white
pack .uno .dos -side bottom
# Se crea una tercera frame que se empaqueta a la derecha.
frame .tres -width 20 -height 20 -bg red
pack .tres -side right

El resultado es el siguiente:

Como puede verse, la tercera frame ocupa sólo una pequeña parte de la zona derecha, y en teoría la frame blanca podría subir todavía algo más, pero esto no es así, debido a que el modelo de cavidad indica que la tercera frame no sólo ocupa su propio espacio físico, sino también toda su cavidad.

 

Opciones del pack

El packer distingue entre espacio para mostrar un widget (display space), y el espacio que le packer le proporciona para representarse (packing space). De esta manera, un widget puede utilizar más (o menos) espacio para empaquetarse del que necesita para mostrarse. El resto del espacio (si sobra algo) queda a lo largo de la cavidad del widget.

Existen una serie de opciones que controlan estos espacios. Son las siguientes:

Opcion -fill

Esta opcion causa que el widget rellene el espacio de packing cuando es mostrado. Un widget puede rellenar el espacio en el eje X , en el Y, o en ambos. La opción por defecto es no rellenar.

Ejemplo 11-5.
# Se crean dos frames y se empaquetan en la parte inferior de la frame principal
frame .uno -width 100 -height 50 -bg grey50
frame .dos -width 40 -height 40 -bg white
pack .uno .dos -side bottom -fill x
# Se crea una tercera frame que se empaqueta a la derecha.
frame .tres -width 20 -height 20 -bg red
pack .tres -side right -fill x


Este ejemplo es exactamente igual al anterior con la única diferencia de la utilización de la opción -fill en el eje x en las tres frames. El resultado es este:

 

 

Como puede verse, las frames .uno y .dos rellenan todo su espacio en el eje x, pero la frame .tres no. Esto es así porque la opción -fill no actúa dentro de cavidad del packing.

Otro uso de la opción -fill es para barras de menú que tienen botones en los extremos.

Ejemplo 11-6
frame .menubar -bg white
frame .body -width 150 -height 50 -bg grey50
# Crea los botones de la barra de menu.
foreach b { boton1 boton2 } {
button .menubar.$b -text $b
}
pack .menubar.boton1 -side left
pack .menubar.boton2 -side right
pack .menubar -side top -fill x
pack .body

El resultado es el siguiente:

Opciones -ipadx y -ipady

Otra forma de tomar más espacio para un widget es utilizar las opciones -ipadx y -ipady, las que propocionan a un widget más espacio dentro del propio widget. Dicho de otra manera, obligan a un widget a mantener una separación entre su borde y lo que haya en su interior.

Ejemplo 11-7
frame .menubar -bg white
frame -body -width 150 -height 50 -bg grey50
# Crea los botones de la barra de menu.
foreach b { boton1 boton2 } {
button .menubar.$b -text $b
}
pack .menubar.boton1 -side left -ipadx 10 -ipady 10
pack .menubar.boton2 -side right
pack .menubar -side top -fill x -ipadx 10 -ipady 10
pack .body

En este caso, se le ha dado más espacio interno a uno de los botones y a la frame blanca.

Opciones -padx y -pady

Estas opciones son similares a las anteriores. La diferencia radica en que si en el caso anterior se obligaba a un widget a mantener una distancia entre su borde y lo que hubiera dentro de él, en este caso se trata de obligar a mantener una distancia entre su borde y lo que haya fuera de él.

Ejemplo 11-8.
. config -borderwidth 10
# Se crea el botón de OK
frame .ok -borderwidth 2 -relief sunken
button .ok.b -text Ok
pack .ok.b -padx 5 -pady 5
# Se crea el borón de cancelar.
button .cancelar -text Cancelar
pack .ok .cancelar -side left -padx 5 -pady 5

En este ejemplo se ha creado un cuadro de diálogo muy sencillo, pero suficiente para mostrar el funcionamiento de las opciones -padx y -pady. El resultado es :

La opción -expand

El comando -expand true permite al widget expandirse en su cavidad. Es importante en el caso de que el usuario redimensione la ventana donde se encuentra el widget; de esta forma, el widget ocupará siempre todo el espacio disponible.

Ejemplo 11-9.
# Se configure la ventana principal con el color negro.
. config -bg black
# Se crean y empaquetan dos frames.
frame .menubar -bg white
frame .body -width 150 -height 50 -bg grey50
# Se crean dos botones en la parte superior.
foreach b { boton1 boton2 } {
button .menubar.$b -text $b
}
pack .menubar.boton1 -side left
pack .menubar.boton2 -side right
# Se permite a la barra de menu rellenar el espacio a lo largo del eje X
pack .menubar -side top -fill x
pack .body

Ahora se redimensiona la ventana:

# Se redimensiona la ventana para que sea mayor.
wm geometry . 200x100

La única frame que ocupa todo su espacio disponible en la cavidad que le corresponde es la blanca, ya que tiene la opción -fill x. Si ahora esta ventana se redimensiona de forma interactiva con el ratón:

Se aprecia que sigue siendo la blanca la única frame que ocupa toda su cavidad.

Utilizando ahora, en el mismo ejemplo que el anterior, la opción -expand true:

Ejemplo 11-10.
# Se configure la ventana principal con el color negro.
. config -bg black
# Se crean y empaquetan dos frames.
frame .menubar -bg white
frame .body -width 150 -height 50 -bg grey50
# Se crean dos botones en la parte superior.
foreach b { boton1 boton2 } {
button .menubar.$b -text $b
}
pack .menubar.boton1 -side left
pack .menubar.boton2 -side right
# Se permite a la barra de menu rellenar el espacio a lo largo del eje X
pack .menubar -side top -fill x
pack .body -fill both -expand true

El resultado es idéntico al caso anterior:

Pero al redimensionarla dinámicamente con el ratón, también la frame gris se redimensiona para ocupar todo el espacio de su cavidad

La opción -anchor

Un widget puede ser posicionado dentro de su espacio de display con la opcion -anchor, la cual "ancla" el widget en una determinada posición. Los posibles valores de esta opción se corresponden con los puntos cardinales de una brújula: n, en, e, se, s, sw, w, nw (norte, nordeste, este, sudeste, sur , suroeste, oeste y noroeste).

Ejemplo 11-11.
# Se configure la ventana principal con el color negro.
. config -bg black
# Se crean y empaquetan dos frames. <>frame .prop -bg white -height 80 -width 20
frame .base -width 120 -height 20 -bg grey50
pack .base -side bottom
label .hola -text Hola
pack .prop .hola -side right -expand true

La frame .base es empaquetada en la parte inferior. Entonces, la frame .prop y el label .hola son empaquetados a la izquierda con la opcion -expand, pero no la opcion -fill.

Si en lugar de hacer el pack como se hizo, se hubiera hecho de esta forma:

pack .prop -side right -expand true -anchor sw
pack .hola -side right -expand true -anchor ne

El resultado habría sido este otro:


Previous Page Next Page


© 1995-98, etsimo WWW team
Última modificación: 19 de Agosto de 1998 - 17:47:07