martes, 3 de febrero de 2009

Organización de widgets en wxPython (Parte VI)

.

Si has llegado aquí mediante un buscador o por simple casualidad, te cuento que estas en la quinta parte de un tutorial que empieza AQUI.

En esta entrega les voy hablar del GridBagSizer.

El GridBagSizer

Un GridBagSizer es una versión mejorada del FlexGridSizer. Lo primero que lo hace diferente, es que el GridBagSizer nos da la posibilidad de agregar un widget en una celda especifica a través de sus coordenadas de fila y columna. La segunda característica que lo diferencia, es la posibilidad de combinar varias celdas de modo que formen una sola.

Haciendo uso de un GridBagSizer, podemos lograr distribuciones de widgets como la de la siguiente imagen:

En esta imagen, quiero que noten la posibilidad que nos da el GridBagSizer de combinar las celdas. El widget de la celda (0,1) ocupa dos filas de alto; el widget de la celda (2,1) ocupa dos columnas de ancho y el widget de la celda (0,3) ocupa tres filas de alto.

A continuación, veremos como hacer el ejemplo que está en la imagen utilizando wxFormBuilder.

Antes de empezar a crear el ejemplo, les voy a comentar un problema que tiene wxFormBuilder con el GridBagSizer. En todos los Sizers anteriores creábamos primero un Frame y luego el Sizer en cuestión. Si bien aquí debiera ser igual, wxFormBuilder tiene un bug que hace que si intentamos agregar un GridBagSizer directamente dentro de un Frame, simplemente no funcione. La versión de wxFormBuilder que estoy usando es la 3.0.57 (Unicode), depende de en que momento estés leyendo esto, tal ves sea una anécdota, pero por ahora tenemos que usar un pequeño truco: primero creamos el Frame, luego un BoxSizer y por ultimo el GridBagSizer; es decir que debemos agregar el GridBagSizer dentro de un BoxSizer, y de este modo ya podemos trabajar.

Dicho esto, veamos como crear el ejemplo paso a paso:

Crear el frame:


Crear el BoxSizer (por el bug de wxFormBuilder que te comenté)
:

Crear el GridBagSizer:


Agregar 8 botones (wxButton), del mismo modo que lo venimos haciendo hasta acá. El Editor de wxFormBuilder se verá así:



Para poder cambiar la ubicación de un widget dentro de un GridBagSizer, usamos las propiedades row y column, para establecer la fila y la columna donde queremos ubicar realmente el widget. Esto lo hacemos seleccionando el widget que queremos reubicar, y cambiamos los valores de estas propiedades en el panel “Object Properties”. Por ejemplo, para mover el botón de la celda (0,1) a la celda (1,0) utilizando wxFormBuilder; seleccionamos el botón contenido en la celda (0,1), escribimos un “1” en la propiedad row y establecemos la propiedad column en “0”. Después de hacer esto, el Editor quedaria así:


A continuación, te muestro los movimientos que deberías seguir haciendo para obtener la distribución de los botones del ejemplo:

Mover el botón de la celda (0,2) a la celda (2,0):


Mover el botón de la celda (0,3) a la celda (0,1):


Mover el botón de la celda (0,4) a la celda (2,1):


Mover el botón de la celda (0,5) a la celda (0,2):


Mover el botón de la celda (0,6) a la celda (1,2):


Mover el botón de la celda (0,7) a la celda (0,3):


En este punto ya tenemos todos los botones en la ubicación correcta. Ahora debemos combinar las celdas necesarias.

Para combinar las celdas, disponemos de las propiedades rowspan y colspan. Con la propiedad rowspan logramos que una celda se combine con cierta cantidad de filas, y con la propiedad colspan combinamos una celda con una cantidad de columnas determinada. Si rowspan y colspan valen “1” (este es el valor por defecto), quiere decir que el widget ocupa solo una fila de alto y una columna de ancho.

Para que se entienda mejor, iremos haciendo las combinaciones necesarias para ir terminando el ejemplo. Lo primero será hacer que la celda (0,1) se extienda hacia la fila de abajo (rowspan=2):

Como puedes ver en la imagen, si bien rowspan vale “2” para la celda (0,1), esta no parece estar ocupando dos filas, ya que el botón que esta contenido en ella, no ocupa dos filas, sino una. En realidad si ocupa dos filas, pero por defecto los widgets dentro del GridBagSizer no crecen en forma automática, es por eso que una ves mas debemos recurrir a los Flags, y activar el Flag wxEXPAND:


Ahora el botón (wxButton) de la celda (0,1) ocupa las dos filas. Para terminar el ejemplo, debemos combinar y expandir las siguientes celdas:

La celda (2,1) debe ocupar dos columnas (colspan=2):


y por último, la celda (0,3) debe ocupar tres filas (rowspan=3):


En la imagen vemos el ejemplo terminado.

Como tal ves notaste, el GridBagSizer es el Sizer mas "complejo" que hemos visto. Si bien, también es cierto que lo podemos definir como el "mas completo y flexible", muchas veces no es la mejor opción a la hora de trabajar, debido a su "complejidad" que hace que las interfaces sean mas difíciles de realizar y mantener, es por esto que en general se suelen usar una combinación de los otros Sizers mas simples, para lograr el mismo comportamiento.

... y ahora: ¿Que sigue?

Finalmente, después de 6 entregas, estamos en condiciones de comenzar a combinar todo lo visto; así que a partir de la próxima parte del tutorial, nos meteremos de lleno en la creación de interfaces “reales”.

Como siempre les digo, comenten si encuentran algo poco claro, algo erróneo o quieren hacer alguna pregunta o sugerencia.

Nos vemos la próxima!

Editado:
Ya esta disponible la parte VII

4 comments

JrcsDev dijo...

Excelente tutorial. Desde anoche lo estoy leyendo. Me servirá para hacerle una GUI a mi cliente de gtalk que estoy haciendo en Ubuntu con python

Anónimo dijo...

Muy buen tutorial, te felicito.

Santi Calvo dijo...

Felicidades por tu tutorial. Creo que es lo mejor que he visto sobre wxFormBuilder...

BA dijo...

No sé si has abandonado ya estos tutoriales relacionados con WxPython, pero este de los sizers me está gustando mucho. Espero que no. Gracias de verdad por tu esfuerzo y claridad.

Publicar un comentario