Download Diapositivas

Document related concepts
no text concepts found
Transcript
wxFormBuilder, un diseñador para
wxPython
Antonio Mario Molina Saorín & Ángel Luis García García
Taller de wxFormBuilder
●
Introducción al Universo de Discurso.
–
●
wxPython y wxFormBuilder
wxFormBuilder.
–
Diseño y creación de interfaces
–
Eventos
–
Herencia y override
Universo de Discurso
●
¿Qué es wxFormBuilder?
●
Breve repaso de wxPython.
●
–
Widgets.
–
Sizers.
–
Eventos.
Requisitos para seguir este taller:
–
Python 2.6.6
–
wxPython 2.8.11
–
Stani's Python Editor
–
wxFormBuilder 3.2
wxFormBuilder, y 1
●
●
●
Desarrollado por José Antonio Hurtado, Juan Antonio Ortega,
Ryan Mulder, Ryan Pusztai, Michal Bliznak.
Es un entorno WYSISWG para diseño gráfico de interfaces
wxWidgets.
A partir del diseño gráfico de componentes permite generar
código C++, XRC y Python (para el framework wxPython).
●
Intuitivo y fácil de utilizar.
●
Contiene muchos widgets (NoteBook, Splitter, …)
●
Utiliza sizers para posicionamiento de widgets.
wxFormBuilder, y 2
●
No es un RAD propiamente dicho, como Microsoft
Visual Studio.
–
Es un diseñador y constructor de interfaces gráficas
que utiliza wxPython como framework gráfico
para Python.
–
Por tanto:
●
●
En wxFormBuilder diseñamos y creamos la interfaz
gráfica.
Con una herramienta de edición de código (IDE,
editor) llamamos a las clases generadas por
wxFormBuilder.
wxFormBuilder, y 3
●
Sitio web: http://wxformbuilder.org/.
●
¿Dónde obtener wxFormBuilder?
–
Para Linux:
●
●
●
–
En repositorios.
LaunchPad.
SourceForge.
Para Windows:
●
SourceForge.
wxFormBuilder, y 4
●
Open Source (licencia GPL).
●
Alternativas a wxFormBuilder:
–
wxGlade.
–
BOA Constructor (un RAD al estilo de Microsoft Visual Studio).
–
PythonCard.
–
wxDesigner.
–
VisualWx.
–
DialogBlocks.
wxPython, y 1
●
wxPython es un framework creado por Robin Dunn, en 1995.
●
Es una librería gráfica para Python (al igual que GTK, Qt y Tkinter).
●
●
Permite crear programas con una interfaz gráfica robusta y de gran funcionalidad, fácil y
simple.
Es un wrapper de la plataforma wxWidgets (escrita en C++).
–
Una adaptación de la biblioteca wxWidgets para ser usada en Python.
●
Es Open Source.
●
Multiplataforma. (Windows, Unix, Mac).
●
Muy documentado.
●
Proyecto muy activo
–
Versión estable: 2.8.12.0 (Abril 2011)
–
Versión desarrollo: 2.9.1.1 (Octubre 2010)
wxPython, y 2
●
Sitio web: http://www.wxpython.org/.
●
Además de wxPython se recomienda la instalación de wxPython Demo:
–
●
contiene la documentación de wxWidgets y multitud de ejemplos.
Material bibliográfico recomendado:
wxPython, y 3
●
●
wxPython sirve para crear aplicaciones gráficas orientadas a eventos.
Un evento es cualquier interacción entre el agente humano y la aplicación, como
puede ser un click de ratón.
–
●
●
●
La generación de un evento provoca una respuesta en el sistema.
A cada evento se le puede asociar un código, mediante un proceso llamado
binding.
El manejador de eventos es el código que se dispara a consecuencia de la
generación de un evento.
Una aplicación wxPython espera a que se generen eventos, asociando los mismos
a un código, llamado manejador de eventos.
wxPython, y 4
●
Estructura básica de una aplicación wxPython:
# Se importan las wx.
import wx
# Se instancia una aplicación wxPython.
app = wx.PySimpleApp()
# Se instancia el contenedor principal.
ventana_principal = wx.Frame(None, -1)
# Mostramos la ventana.
ventana_principal.Show()
# Esperamos a los eventos.
app.MainLoop()
wxPython, y 5
●
Un widget es cualquier componente gráfico con el
que interactuar en wxPython (botones, cajas de
texto, calendarios, sliders, ...).
–
●
wx.Frame es un widget contenedor, similar a una
ventana de Microsoft Windows.
Los widgets pueden disponerse con wx.Point y
wx.Size, mediante coordenadas, dentro de un
contenedor. Otra forma de hacerlo es mediante el
uso de sizers.
wxPython, y 6
●
Un sizer es un mecanismo de disposición de
widgets en wxPython.
–
Maneja el tamaño y posición de sus widgets, basado
en un conjunto de reglas.
–
Se asigna a un contenedor (wx.Panel ó wx.Frame).
–
Es un algoritmo para disponer o enmarcar un grupo
de widgets.
–
Los subwidgets que se crean dentro de un contenedor
deben de añadirse por separado al sizer.
–
El sizer administra la posición de los widgets.
wxPython, y 7
●
●
Un sizer en wxPython es un objeto con el único
propósito de administrar el posicionamiento de un
conjunto de widgets dentro de un contenedor.
El sizer es la representación de un algoritmo de
posicionamiento de pantalla (no un contenedor ó
widget).
●
Un sizer es una instancia de la clase wx.Sizer.
●
Un sizer puede estar incluido en otro sizer.
wxPython, y 8
●
●
Tipos de sizers:
–
wx.BoxSizer
–
wx.FlexGridSizer
–
wx.GridSizer
–
wx.GridBagSizer
–
wx.StaticBoxSizer
En este taller veremos:
–
wx.BoxSizer & wx.FlexGridSizer
Herramientas a utilizar
●
●
●
●
Python 2.6.6. Es la versión, junto a la 2.7, que funciona sin
ningún tipo de problemas en wxPython 2.8.X.
wxPython 2.8.11.0. Versión estable, junto a la 2.8.12.0.
Stani's Python Editor. Es uno de los IDE's gratuitos más
potentes y livianos, multiplataforma, con completitud,
indentación y coloreado de código, además de otras muchas
cualidades.
wxFormBuilder 3.2 Beta. Es la última versión.
Creación de un proyecto, y 1
Creación de un proyecto, y 2
Guardamos el proyecto con Ctrl+S, ó File/Save, ó haciendo click en botón Guardar.
wxFormBuilder: Partes
●
wxFormBuilder está compuesto de 4 partes:
–
Object Tree:
Tree El árbol de objetos que compone la interfaz diseñada.
–
Component Pallete:
Pallete Conjunto de widgets y sizers disponibles para diseñar
la interfaz.
–
Editor.
Editor Se compone de 4 hojas:
●
Designer: Diseño gráfico de la interfaz.
●
C++: Código C++ generado a partir del diseño en el Designer.
●
●
–
Python: Código Python generado a partir del diseño en el
Designer.
XRC: Código XML generado a partir del diseño en el Designer.
Object Properties:
Properties Propiedades y eventos de los componentes del
Designer.
Interfaz 1
Creamos un contenedor wx.Frame.
Interfaz 1
Incluimos dentro del contenedor un wx.BoxSizer.
Interfaz 1
Incluimos un wx.StaticText; cambiamos la propiedad label, y configuramos el sizeritembase, es decir,
cómo queremos que se comporte el widget dentro del sizer base (que lo contiene). Para ello activamos
bandera wxALIGN_CENTER y aumentamos el borde a 25.
Interfaz 1
Incluimos 3 wx.TextCtrl.
Interfaz 1
¿Cómo redimensionar las 3 cajas de texto? Configurando su posición
dentro del sizer base. Para ello hay que activar el flag wx.EXPAND.
Interfaz 1 – Código Python generado
Conforme se va diseñando la interfaz gráfica se va generando el código Python (Editor, pestaña
Python). Para crear el fichero Python pulsar F8, o File/Generate Code o click en icono de generar
código.
Importando la Interfaz 1
●
●
Una vez creada la interfaz y generado el código
Python, creamos el módulo que llamará a dichas
clases. En dicho módulo hay que crear una
aplicación wxPython, pues wxFormBuilder no lo
genera (en contraposición con otros diseñadores,
como wxGlade).
Abrimos Stani's Python Editor.
–
Creamos un módulo: datos.py
Importando la Interfaz 1
●
Creamos el módulo con el siguiente código y
ejecutamos:
Ejecutando la Interfaz 1
●
●
Se ha creado una aplicación wxPython, y toma como
contenedor principal una instanciación de la clase generada
en wxFormBuilder.
Cosas a tener en cuenta:
–
Si se redimensiona el widget contenedor, se
redimensionan sus widgets contenidos,
automáticamente.
–
No se puede pasar de un widget wx.TextCtrl a otro
mediante la tecla tabulador (TAB), como cabría
esperar.
●
¿Solución? Usar paneles.
Modificando la Interfaz 1
Incluimos un widget wx.Panel dentro del wx.BoxSizer principal.
Modificando la Interfaz 1
Si se incluyen widgets dentro de un contenedor wx.Panel aparece la propiedad de
navegación entre widgets a través del tabulador. Todo posicionamiento de widgets se
realiza con sizers, por lo que será necesario crear uno dentro del wx.Panel.
Modificando la Interfaz 1
Se pueden mover los widgets wx.TextCtrl y wx.StaticText mediante la técnica de Drag &
Drop, capturando y soltando los widgets de un sizer al interior de otro.
Ejecutando de nuevo la Interfaz 1
●
●
Guardamos el proyecto y volvemos a generar el
código Python.
Volvemos a Stani's, y sin cambiar nada (en realidad
no es necesario), ejecutamos. Ahora aparece la
funcionalidad de navegación entre widgets con la
tecla TAB.
–
UTILIZAR SIEMPRE PANELES.
Eventos en wxFormBuilder
●
●
●
Se ha creado la primera interfaz en wxFormBuilder,
completamente funcional.
A partir de este diseño se creará un frame con dos
botones (en sentido horizontal) de ACEPTAR y
CANCELAR.
Se crearán los eventos de click en los botones
anteriores.
Eventos en wxFormBuilder
Sobre MyFrame1 botón derecho/Paste y creamos una copia de Frame1
Eventos en wxFormBuilder
Eventos en wxFormBuilder
●
Renombramos nuevo widget contenedor a MyFrame2, y
modificamos algunos atributos.
Eventos en wxFormBuilder
Creamos un sizer horizontal, dentro del sizer principal del contenedor MyFrame2.
Fijarse en la propiedad orient, que la hemos cambiado a wxHORIZONTAL.
Eventos en wxFormBuilder
Creamos 2 wx.Button dentro del nuevo sizer.
Eventos en wxFormBuilder
Vamos a cambiar la posición de los botones ACEPTAR y CANCELAR. Los vamos a
justificar a la derecha. Para ello hay que desactivar la bandera wxEXPAND del sizer
contenedor de los botones y activar la bandera wxALIGN_RIGHT.
Eventos en wxFormBuilder
Cambiamos los nombres a los botones y creamos los eventos de click en botones
ACEPTAR y CANCELAR. En realidad es añadir los nombres de los manejadores de
eventos que se lanzarán cuando se den los eventos pertinentes.
Hay 2 maneras de crear el nombre del manejador de eventos:
1) Haciendo doble click sobre el evento, y genera de manera automática el
nombre del manejador de eventos.
2) Insertando el nombre directamente junto al evento que queremos tratar.
Eventos en wxFormBuilder
Podemos ver el código Python que wxFormBuilder genera automáticamente:
Eventos en wxFormBuilder
Guardamos proyecto y generamos código Python en wxFormBuilder. Volvemos a Stani. Tal como se ha visto hay
que hacer override de los manejadores de eventos para darle funcionalidad. Habrá que crear una clase Frame
que herede de MyFrame2, y hacer override de los manejadores de eventos.
Conclusiones...
●
Conceptos vistos:
–
Proyecto wxFB.
–
Widgets contenedores Frame y Panel.
–
Posicionamiento con sizer wx.BoxSizer.
–
Eventos.
–
Herencia de widgets y override de manejadores de
eventos.
Interfaz 2
●
●
●
Vamos a crear un segundo proyecto, denominado gestion_datos, que
generará el fichero Python gestion_datos_vista.py.
Crearemos paneles como widgets contenedores, para ver la reusabilidad de
los mismos.
Veremos el uso del flag Proportion en un sizer.
Interfaz 2
Se va a diseñar el frontend de una posible aplicación de gestión, con widgets avanzados,
tales como NoteBook, Splitters ó Choices. Se verá el potencial de los sizers como
algoritmos de posicionamiento de widgets.
La aplicación consta de un único Frame y 3 paneles. Cada Frame contenedor de la
aplicación será la instanciación del Frame generado por wxFB.
Se practicará como pasar estructuras de datos a los componentes gráficos para que
muestren información.
Interfaz 2
Los conceptos de esta segunda interfaz son idénticos a la primera, a excepción que se
verán nuevos widgets más complejos a la vez que útiles y sofisticados.
El proyecto wxFB,
wxFB así como el código Python para llamar a las clases de wxPython
están en los ficheros adjuntos a este material.
Menús en wxFormBuilder
●
●
●
Como se puede observar en el Forms del Component Pallete,
existen 5 componentes que se pueden instanciar sin necesidad de
un contenedor padre, a saber, Panel, Frame, Dialog y los widgets
de menús MenuBar y ToolBar.
ToolBar
Además en el Component Pallete está la pestaña Menu/Toolbar,
Menu/Toolbar
que contiene toda una colección de widgets para utilizar en menús.
Un menú se puede crear:
–
Dentro de un Frame.
–
Como un contenedor, al estilo de Paneles ó Frames (es decir,
se crea una clase en el código Python generado).
Menús en wxFormBuilder
Creamos un nuevo proyecto, llamado menus_wx, y el fichero Python a generar será
menus_wx_vista.py.
Menús en wxFormBuilder
Diseño de un Frame con un sistema de menú integrado.
Menús en wxFormBuilder
Menús en wxFormBuilder
Menús en wxFormBuilder
Menús en wxFormBuilder
La herramienta del Editor de menú da como resultado el Object Tree de widgets de menú.
Menús en wxFormBuilder
Podemos comprobar las opciones de elementos de menú tipo Radio (excluyentes).
Menús en wxFormBuilder
Y para las opciones de menú de tipo check.
Eventos en menús
Crear eventos de elementos de menú es trivial, tal como se ha visto anteriormente.
Únicamente hay que seleccionar el item de menú deseado, e ir a Events (Objects
Properties), para ingresar el nombre del manejador de eventos asociado al evento en
cuestión, en este caso, OnMenuSelection.
NOTA: Crear eventos OnMenuSelection para elementos de menú de Nuevo y Abrir (Archivo).
Menús en wxFormBuilder
En el código generado por wxFormBuilder encontramos los identificadores de los
elementos de menú. Al crear un Tool dentro de un ToolBar hay que especificar el ID del
elemento del menú creado, para enlazar el manejador de eventos.
Menús en wxFormBuilder
Creamos un ToolBar, y dentro de él, un widget Tool (todo esto seleccionado de la pestaña
Menu/Toolbar del Component Pallete). Fijarse en el atributo id del widget Tool, que se ha cambiado
por ID_ABRIR, de modo que cuando se haga click en él se lanzará el manejador de eventos asociado
al elemento de menú Abrir. Además se ha creado un StatusBar, enlazando el atributo statusbar del
widget Tool al mismo (automáticamente), con el texto “Abrir un documento”. Cuando se pase el ratón
por encima del widget Tool aparecerá dicho texto en el widget StatusBar.
Menús en wxFormBuilder
Volvemos a Stani, y creamos el módulo menus_wx.py, con el siguiente contenido:
Ejecutamos y vemos la solución esperada...
Conclusiones...
●
Hemos visto como crear menús en contenedores de tipo wx.Frame.
–
Menús.
–
Elementos de menús (normal, checked, radio).
–
Submenús.
–
Eventos en menús.
–
Barra de herramientas (ToolBar).
–
Elementos de la barra de herramientas (Tool).
●
–
Asociar eventos de Tool a elementos de menús.
Llamar a las clases generadas por wxFormBuilder desde un editor, en este
caso, Stani's Python Editor, y hacer override en algunos manejadores de
eventos.
Componente Custom Control en wxFB
●
●
De lo que se trata es de generar código Python para
un widget que todavía no está soportado en
wxFormBuilder.
Vamos a crear un nuevo proyecto, llamado
cc_proyecto, que generará cc_proyecto_vista.py.
Componente Custom Control en wxFB
Para ver cómo funciona este widget vamos a crear un proyecto en wxFormBuilder, en
donde insertaremos un widget LEDNumberCtrl,
LEDNumberCtrl el cual no está soportado actualmente
(en la versión 3.2) por wxFormBuilder.
Componente Custom Control en wxFB
Diseñamos un Frame que contendrá un Panel,
Panel que a su vez contendrá un CustomControl.
CustomControl
NOTA: Darse cuenta que hemos renombrado todos los widgets, en especial el Custom
Control, ahora LedControl.
Componente Custom Control en wxFB
Modificamos las propiedades del CustomControl LedControl:
Para generar código Python de estas propiedades solamente nos interesan 2, a saber:
name (el nombre del widget, que se utiliza para añadirlo al sizer) y construction (la
llamada para instanciar la clase y crear el objeto cuyo nombre ha sido declarado en
name, y que tiene que ser atributo de la clase). Por tanto vamos a darle a nuestro nuevo
widget como name LedControl. Y el construction será: self.LedControl =
wx.gizmo.LedNumberCtrl(self, -1). Darse cuenta que el LedControl tiene que ser
atributo de la clase generada (es por ello lo del self).
Componente Custom Control en wxFB
Configuración final de las propiedades del LedControl:
Custom Control en Stani
Creamos el módulo cc_proyecto.py en Stani, con el siguiente código:
Custom Control en Stani
¡CONSEGUIDO!
Conclusiones sobre el taller de wxFB
●
●
●
Se ha introducido a la herramienta de diseño de interfaces
gráficas wxFormBuilder, en especial, para la generación de
código Python a partir del framework wxPython.
Se han visto los conceptos de widget, evento y sizer.
Se ha probado la herencia de las clases generadas por wxFB y el
override de métodos (manejadores de eventos).
●
Se han diseñado menús de Frames.
●
Se ha comprobado el widget Custom Control.
Taller de wxFB – Caldum 2011
Universidad de Murcia
Muchas gracias a todos.
Antonio Mario Molina Saorín
Ángel Luis García García