Si has llegado aquí mediante un buscador o por simple casualidad, te cuento que estas en la segunda parte de un tutorial que empieza AQUI.
Trabajando con los Sizers
Todos los sizers tienen algunas características en común; y otras, que hacen que cada uno de ellos sea único. Podríamos ver una a una cuales son las similitudes y cuales las diferencias para luego pasar a la practica con cosas concretas, pero no quiero que tengas que leer un montón de teoría antes de poder ver algo de practica, es por esto que iré intercalando la teoría y la practica de manera que el tutorial no se te haga muy tedioso. Creo que va a ser mas fácil partir de un sizer en particular (el GridSizer en este caso), y luego ir explicando en que se parecen y en que se diferencian a medida que vayamos avanzando con cada uno de los otros sizers.Hay distintos enfoques a la hora de trabajar con interfaces gráficas con Wxpython:
1- Escribir todo el código necesario para ir generando la interface gráfica; llamando a las funciones de wxPython que permiten crear los distintos widgets (botones, listas, etc.) desde la propia aplicación que estemos desarrollando.
2- Generar un archivo XML que describe la interface gráfica, y que luego podemos cargar desde la aplicación.
3- Utilizar un IDE para diseñar la interface gráfica. En este método, trabajamos de la misma manera que en método 2, excepto que es el propio IDE el que genera el archivo XML para que después lo carguemos desde nuestra aplicación.
De los tres métodos, vamos a empezar por el tercero. El IDE que vamos a usar será wxFormBuilder, pero existen otros como XRCed y wxGlade por nombrar sólo algunos mas. Este método es el mas práctico porque (al igual que en el segundo) logramos independizar la parte gráfica de la aplicación, del resto del código de la aplicación en sí. A diferencia del segundo método, es mucho mas fácil delegar la tarea de escribir el archivo XML en el IDE. Mas adelante veremos el primero y segundo metodo tambien.
En mi caso trabajo sobre Ubuntu Intrepid Ibex (8.10), pero wxFormBuilder es un IDE multiplataforma. Por lo menos en el caso de la mayoría de las distribuciones populares de Linux, ya viene en los repositorios. Los usuarios de Windows y Mac los pueden descargar desde el sitio del proyecto. wxFormBuilder es libre y gratuito.
A continuación te muestro una captura de pantalla para que te vayas familiarizando con el programa:

Una vez que tenemos wxFormBuilder instalado en nuestro sistema, ya estamos listos para empezar a trabajar.
Antes de poder crear un Sizer, debemos generar algún tipo de formulario que lo contenga. Para este ejemplo crearemos un Frame como contenedor, el cual visualmente no es mas que una clásica ventana (con su borde, botones de cerrar, minimizar y maximizar, etc). Para esto vamos a la solapa “Forms” de la paleta de componentes de wxFormBuilder y pulsamos el botón "Frame". Veamos una imágen para que se entienda mejor:



1- El panel izquierdo de wxFormBuilder ("Object Tree"), nos muestra toda la interface en forma de árbol. En la imagen podemos apreciar que la raíz es el proyecto en si (Proyect1 en este caso), inmediatamente después se encuentra el Frame (llamado MyFrame2), y por último, dentro del Frame esta el GridSizer que acabamos de agregar (cuyo nombre es gSizer1).
2- Si miramos bien dentro del Frame que creamos, veremos que el GridSizer esta representado por un rectángulo rojo que ocupa todo el interior del Frame.
3- El panel derecho de wxFormBuilder ("Object Properties"), nos muestra las propiedades del objeto que esta seleccionado actualmente en el Editor.
Para ver como se comporta el GridSizer, iremos agregando algunos widgets dentro de éste. A modo de ejemplo, agregaremos cuatro botones. Esto realmente no tiene ninguna complejidad, ya que el modo de trabajo es el mismo que usamos hasta aquí. Ante todo, verificamos que esté seleccionado "gSizer1" en el "Object Tree" de wxFormBuilder; de modo que el IDE "sepa" que los botones irán dentro del GridSizer, luego vamos a la solapa “Common” y pulsamos el botón “wxButton”. Esto agregará el primer botón al GridSizer.


Es importante que le vayas prestando atención al "Object Tree" de wxFormBuilder. Este "árbol" nos da una clara visión de como se relacionan los distintos elementos de nuestra interface. Entender este “árbol” también te servirá mucho si en algún momento decides trabajar con el IDE XRCed (en otro tutorial lo veremos).
Veamos un poco mas en detalle el GridSizer.
Grid Sizer (wx.Grid Sizer)
Como ya hemos dicho, el GridSizer consiste en una grilla bidimensional, en la cual se organizan los distintos widgets que necesitemos. Gráficamente un GridSizer no es mas que una grilla, donde en cada celda podemos posicionar un widget.El primer widget que se agrega a un GridSizer se ubica en la esquina superior izquierda de la grilla; el resto se ubican de izquierda a derecha, y al llegar a la ultima columna de una fila, se continua en la primera columna de la fila inmediatamente inferior hasta llegar a la ultima celda de la grilla, que corresponde a la esquina inferior derecha de la misma. Este comportamiento, lo habrás visto bien claro si fuiste haciendo el ejemplo de agregar cuatro botones dentro del GridSizer con wxFormBuilder; cada vez que pulsas el botón que agrega un wxButton, puedes observar donde se posiciona el botón dentro de la grilla. Si no hiciste el ejemplo, te invito a que lo hagas!.
Al redimensionar un GridSizer, cada celda de este, agranda o disminuye su tamaño proporcionalmente, pero por defecto, los widgets contenidos en cada una de las celdas, mantienen su tamaño original, y quedan “anclados” a la esquina superior izquierda de la celda en la que se encuentran. Veamos una captura, donde vemos 2 veces una misma ventana, pero antes y después de ser redimensionada. La ventana contiene un GridSizer que tiene cuatro botones en su interior (el ejemplo que hicimos antes).

Como hemos visto; al crear un GridSizer con wxFormBuilder, nuestra grilla es de 2 X 2 en forma predeterminada, pero obviamente tenemos una forma de cambiar esto. Entre las propiedades particulares del GridSizer se encuentran Rows y Cols, las cuales nos permiten establecer la cantidad de filas y columnas respectivamente. Si lo deseamos, también podemos especificar que haya un espacio entre las distintas celdas; para esto contamos con la propiedad hgap para crear un espacio entre las filas, y vgap para lograr el espaciado entre las columnas. El valor de vgap y hgap, es un numero entero que representa el espaciado en pixeles. En la imagen siguiente, vemos una una grilla de 3 X 2, con un espacio horizontal entre las celdas de 2px y un espaciado vertical entre celdas de 3px:
Para lograrlo, simplemente seleccionamos el GridSizer ("gSizer1") desde el “Object Tree” y luego establecemos los valores en el panel de propiedades (rows=2, cols=3, vgap=3 y hgap=2).
Si bien dijimos que todas las celdas tienen el mismo tamaño, esto no quiere decir que todos los elementos que estén en cada una de ellas, también deban tener las mismas dimensiones ni tampoco la misma posición dentro la celda.
Como dijimos antes, al agregar un elemento en un GridSizer, por defecto éste queda posicionado en la esquina superior izquierda de la celda que le corresponda, y su tamaño NO se ve afectado al cambiar el tamaño del sizer. Este comportamiento puede ser modificado a través de los Flags. Los Flags entran dentro de las características comunes a todos los widgets que se encuentren contenidos en un Sizer. Para entender mejor de que hablamos, veremos cuales son los Flags y para que sirve cada uno de ellos.
Flags para establecer la alineación de los widgets
Las opciones disponibles para alinear los widgets que agregamos a los Sizers son las siguientes:wx.ALIGN_TOP: El widget es alineado en la parte superior de la celda en la que se encuentre, si se omite, esta es la opcion por defecto.
wx.ALIGN_BOTTOM: El widget se alinea en la parte inferior de la celda en la que es insertado.
wx.ALIGN_LEFT: El widget es alineado a la izquierda dentro la celda en la que se encuentre, si se omite, esta es la opcion por defecto.
wx.ALIGN_RIGHT: El widget es alineado a la derecha dentro la celda en la que se encuentre.
wx.ALIGN_CENTER_HORIZONTAL: El widget es centrado en forma horizontal. Se omite el valor de wx.ALIGN_LEFT y wx.ALIGN_RIGHT.
wx.ALIGN_CENTER_VERTICAL: El widget es centrado en forma vertical. Se omite el valor de wx.ALIGN_TOP y wx.ALIGN_BOTTOM.
wx.ALIGN_CENTER: El widget se alinea en la centro de la celda en la que es insertado. En este caso se omiten todas las opciones anteriores.
wx.EXPAND: El widget toma el mismo tamaño que la celda en la que se encuentra.
wx.FIXED_MINSIZE: El widget mantiene siempre su tamaño mínimo (Luego volveremos sobre este punto).
wx.SHAPED: El widget cambiara su tamaño de forma proporcional, manteniendo su relación de aspecto (luego lo veremos con un ejemplo, para que se entienda mejor).
wx.GROW: Funciona igual que wx.EXPAND.
Flags para establecer un borde (espacio) entre los widgets
Además de poder cambiar la alineación de los widgets, tenemos la posibilidad de dejar un borde (espacio) entre el widget y la celda que lo contiene. Para establecer este valor, podemos combinar las siguientes opciones junto con las de alineación que vimos anteriormente:wx.TOP: Establece que el espacio especificado en la propiedad “border”, sea aplicado en la parte superior del widget.
wx.LEFT: Establece que el espacio especificado en la propiedad “border”, sea aplicado a la izquierda del widget.
wx.RIGHT: Establece que el espacio especificado en la propiedad “border”, sea aplicado a la derecha del widget.
wx.BOTTOM: Establece que el espacio especificado en la propiedad “border”, sea aplicado en la parte inferior del widget.
wx.ALL: El espacio se establece a todos los lados del widget (Arriba, Izquierda, Derecha y Abajo). Es la suma de las cuatro opciones anteriores juntas.
Luego veremos algunas imágenes donde se puedan apreciar los resultados de combinar estos valores de distintas formas.
Para que esta segunda parte no se haga mas larga, vamos a dejar aquí. En esta parte, hemos avanzado bastante, y cada vez estamos mas cerca de poder crear una interface mas “real” (léase útil).
Repasando un poco, hasta aquí dijimos que existen tres métodos para trabajar con interfaces gráficas con wxPython, y que por ahora usaremos la alternativa del IDE. Estuvimos viendo como se trabaja con wxFormBuilder, hablamos de los Flags, y tenemos una idea mas clara de como funciona el GridSizer.
Para dominar de forma fluida el diseño de interfaces gráficas con wxPython, se requiere mucha práctica. Al principio puede ser un poco desalentador, ya que cuesta mucho lograr lo que uno tiene en mente; y sobre todo si eres un desarrollador que viene de otros lenguajes (como Visual Basic, por ejemplo) donde la forma de trabajo es bastante distinta, pero con el tiempo te darás cuenta de las ventajas que tiene esta manera de hacer las cosas, y podras ir logrando lo que te propones.
Cualquier duda o sugerencia, puedes comentar.
Editado:
Ya esta disponible la parte III
7 comments
gracias muy interesante
La explicación es realmente muy buena!
Gracias a ustedes por interesarse en mis artículos.
Saludos!
Gracias que bueno que haya bastante información sobre esto, era lo que mas me costaba trabajo en wxpython. Gracias
Hola Jacob, te cuento que lo que me decidió a escribir estos tutoriales fue justamente lo que vos decís, y es que verdaderamente cuesta mucho encontrar información sobre este tema, y mucho mas si buscas algo en nuestro idioma.
Un saludo!
Muchísimas gracias por este tutorial!
Estoy trabajando en un proyecto y necesito hacer una interficie gráfica para mi programa. Es la primera vez que uso python y no sabia ni por donde empezar con la interficie... Realmente es un gran tutorial!
Felicidades!
Muchisimas gracias maestro! La verdad que me viene al pelo este tutorial porque en realidad programo en c++ pero queria utilizar WxFormbuilder para la interfaz y no entendia bien el tema de los sizers! Muy bueno lo tuyo.! Felicitaciones
Publicar un comentario