Introducción rápida a wxPython

Carlos Zayas Guggiari
carlos@carloszayas.com

¿Qué es wxPython?
wxPython es una adaptación de wxWidgets para el lenguaje de programación Python. A su vez, wxWidgets es un conjunto de funciones para el desarrollo de interfaces gráficas en lenguaje C++. Si queremos programar aplicaciones en Python que utilicen interfaces gráficas, wxPython nos provee de todo lo necesario.

¡Hola, Mundo!
Es casi tradicional que para toda introducción a un lenguaje de programación (o, como en este caso, a una extensión del lenguaje) se use un ejemplo del tipo “Hola, Mundo”:
01 02 03 04 05 06 07 08 09 10 import wx aplicacion = wx.App() marco = wx.Frame(None,-1,"Hola Mundo") panel = wx.Panel(marco,-1) texto = wx.StaticText(panel,-1,"Hola, Mundo!") marco.Show(True) aplicacion.MainLoop()
“Hola, Mundo” en Python con wxPython.

Las líneas en blanco no son necesarias; sólo se insertaron para dar mayor legibilidad al programa. En total, sólo se necesitan las siete líneas que aparecen escritas. Un programa del tipo “Hola, Mundo” simplemente imprime un mensaje en pantalla. Al ejecutarlo, obtenemos una ventana con el siguiente aspecto:

En la siguiente página analizaremos línea por línea este programa.

Análisis de “Hola, Mundo”
Lo primero que tenemos que hacer es importar el módulo wxPython, que se llama wx:
import wx

Un programa wxPython debe tener un objeto aplicación (App) y por lo menos un objeto marco (Frame). Un objeto se crea al asignar una clase a una variable. La variable es el nombre del objeto:
aplicacion = wx.App()

Ya tenemos creado el objeto aplicación, que es una instancia de la clase App del módulo wx. Hagamos lo mismo para obtener un marco:
marco = wx.Frame(None,-1,"Hola Mundo")

Ya tenemos creado el marco. Los parámetros necesarios son: parent, id y title. Parámetro parent (progenitor) id (identificador) title (título) Valor dado
None -1 “Hola, Mundo”

Explicación Ventana a la que pertenece el marco. Para el marco inicial, el valor es “Ninguno” (None). Identificador del marco. Si es -1, éste se genera de forma automática. Texto que aparecerá en la barra de título de la ventana.

Hay otros parámetros disponibles para Frame, pero éstos son los únicos obligatorios. Necesitamos un contenedor para los demás elementos (widgets) de nuestra interfaz gráfica. La clase que hay que instanciar esta vez se llama Panel:
panel = wx.Panel(marco,-1)

En esta ocasión, el parent de nuestro panel es el marco que definimos antes. El segundo parámetro (-1) vuelve a dejar en manos de wxPython la elección de un número identificador. Ya tenemos el marco (que básicamente define la ventana) y el panel que contendrá los demás elementos. Es hora de insertar uno dentro del panel. Probemos con una simple etiqueta de texto:
texto = wx.StaticText(panel,-1,"Hola, Mundo!")

La clase StaticText devuelve un objeto de tipo “texto estático”, es decir, una etiqueta de texto cuyo contenido no podrá ser modificado directamente por el usuario. Ya tenemos nuestra ventana terminada. Ahora sólo falta mostrársela al mundo:
marco.Show(True)

¡Listo! Pero, a diferencia de los programas procedurales, que funcionan en base a una secuencia controlada de eventos, un programa orientado a eventos funciona en base a eventos que ocurren en cualquier momento. Por este motivo, wxPython necesita seguir teniendo el control, cosa que logra mediante el método MainLoop (“ciclo principal”):

aplicacion.MainLoop()

Una vez que el usuario cierre la ventana de nuestra aplicación, el ciclo principal finalizará junto con la ejecución del programa.

“Hola, Mundo” con clase
Para un objetivo tan simple como el que plantea un programa tipo “Hola, Mundo”, no hace falta aumentar el nivel de orientación a objetos, pero para darnos una idea del aspecto que podría tener un programa implementado con clases, aquí va el listado:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 import wx class Marco(wx.Frame): def __init__(self, parent, id, title): wx.Frame.__init__(self, parent, -1, title) panel = wx.Panel(self, -1) texto = wx.StaticText(panel, -1, "Hola, Mundo!") class Aplicacion(wx.App): def OnInit(self): marco = Marco(None, -1, "Hola Mundo") self.SetTopWindow(frame) marco.Show(True) return True if __name__ == '__main__': aplicacion = Aplicacion() aplicacion.MainLoop()
“Hola, Mundo” con clases.

Definimos dos clases, Marco y Aplicacion, que heredan sus características respectivamente de las clases Frame y App.
class Marco(wx.Frame): class Aplicacion(wx.App):

En la línea 10, la función OnInit es obligatoria, y debe retornar un valor verdadero (True).
def OnInit(self): return True

En la línea 12, el método SetTopWindow coloca a nuestra ventana al frente de cualquier otra ventana que esté presente en el escritorio.
self.SetTopWindow(frame)

En la línea 16, la estructura condicional if ejecutará su bloque interno sólo si el programa es ejecutado directamente por Python, y no importado como módulo.
if __name__ == '__main__': aplicacion = Aplicacion() aplicacion.MainLoop()