Professional Documents
Culture Documents
Objetivos:
Conocer las tecnicas basicas de programacion de GUIS
Comprender cada uno de los metodos y parametros usados por wxPython
Servir de base para el desarrollo de nuestras propias aplicaciones
Temas:
La creacion de un programa con interfaz de usuario grafica GUI
Creacion de widgets
Incorporacion de widgets en los contenedores
Vincular y manipular eventos
Manipular los valores de los widgets
El documento esta escrito de manera lineal y con la informacion estrictamente necesaria
para comprender lo que se prentende enseñar, se explica paso a paso y de manera
incremental la creacion de un pequeña aplicacion detallando los aspectos necesarios para
la comprension sin abundar en detalles que puedan resultar confusos, luego el lector
podra profundizar en los conceptos necesarios, para ello al final del documento se sugiere
lectura relacionada.
Paso 3: El constructor
Un GUI es una jerarquía de objetos, un botón puede estar contenido en un panel que
figura en una solapa que es contenido en una ventana, etc.
Por lo tanto, cada elemento gráfico tiene un padre (su contenedor, por lo general). Por lo tanto
tambien tiene un constructor padre (parent) como parámetro. Hacer un seguimiento de los padres es
muy útil cuando tenemos que mostrar/ocultar un grupos de widgets, redibujar la pantalla o
simplemente destruirlas cuando la aplicación termina. Asi, simpleapp_wx hereda de wx.Frame, por
lo que tenemos que llamar al constructor wx.Frame (wx.Frame.__init__ ()).
#!/usr/bin/python
try:
import wx
except ImportError:
raise ImportError,"Se requiere el modulo wxPython"
class simpleapp_wx(wx.Frame):
def __init__(self,parent,id,title):
wx.Frame.__init__(self,parent,id,title)
El objeto wx.Frame tiene dos parámetros: id (identificador del widget) y title (el título de la
ventana).
if __name__ == "__main__":
app = wx.App()
frame = simpleapp_wx(None,-1,'Mi aplicacion')
if __name__ == "__main__":
app = wx.App()
frame = simpleapp_wx(None,-1,'Mi aplicacion')
app.MainLoop()
Podremos ver nuestro programa en accion, por una parte es estimulante ver una ventana
en modo grafico con todos los botones y el aspecto identico al resto de nuestras ventans,
pero por otra parte es decepcionante ver la ventana vacia, por lo que en los proximos
pasos iremos poblandola con widgets.
if __name__ == "__main__":
app = wx.App()
frame = simpleapp_wx(None,-1,'Mi aplicacion')
app.MainLoop()
Agregar el widget
Ahora, lo agregaremos a nuestros gestor de diseño (GridBagSizer).
Llamamos al metodo .Add() de nuestra grilla, le pasamos el widget que acaba de crear (self.entrada)
y sus coordenadas de ubicacion en la grilla (0,0) y (1,1) que es el espaciado alrededor del widget.
En nuestro caso, el widget no se extienden a varias celdas, wx.EXPAND le dice al gestor de diseño
(grilla) que debe ampliar la entrada de texto si su celda es redimencionada.
#!/usr/bin/python
try:
import wx
except ImportError:
raise ImportError,"Se requiere el modulo wxPython"
class simpleapp_wx(wx.Frame):
def __init__(self,parent,id,title):
wx.Frame.__init__(self,parent,id,title)
self.parent = parent
self.initialize()
def initialize(self):
grilla = wx.GridBagSizer()
self.entrada = wx.TextCtrl(self,-1,value=u"Ingrese un texto:")
grilla.Add(self.entrada,(0,0),(1,1),wx.EXPAND)
self.SetSizerAndFit(grilla)
self.Show(True)
if __name__ == "__main__":
app = wx.App()
frame = simpleapp_wx(None,-1,'Mi aplicacion')
app.MainLoop()
Tenemos una ventana con un solo campo de texto. Usted puede incluso ingresar en algún
texto por teclado. Pero tenemos un problema, el campo de texto no cambia de tamaño
cuando redimenciono la ventana. No se preocupe, hay una buena razón para esto, le
dijimos al campo de entrada de texto que debia redimensionarse automáticamente si su
columna o celda se expande, pero aún no le especificamos al gestor de diseño (grilla) que
cuando la ventana se redimensiona tambien lo debe hacer la grilla. Ya veremos como
hacerlo mas adelante.
if __name__ == "__main__":
app = wx.App()
frame = simpleapp_wx(None,-1,'Mi aplicacion')
app.MainLoop()
Observe como ubicamos el nuevo widget, el boton, usando las coordenadas (0,1) sin
espaciado. En este punto tenemos una ventana con un campo de texto y un botón.
class simpleapp_wx(wx.Frame):
def __init__(self,parent,id,title):
wx.Frame.__init__(self,parent,id,title)
self.parent = parent
self.initialize()
def initialize(self):
grilla = wx.GridBagSizer()
self.entrada = wx.TextCtrl(self,-1,value=u"Ingrese un texto:")
grilla.Add(self.entrada,(0,0),(1,1),wx.EXPAND)
boton = wx.Button(self,-1,label="Pulsame !")
grilla.Add(boton, (0,1))
self.etiqueta = wx.StaticText(self,-1,label=u'Hola !')
self.etiqueta.SetBackgroundColour(wx.BLUE)
self.etiqueta.SetForegroundColour(wx.WHITE)
grilla.Add( self.etiqueta, (1,0),(1,2), wx.EXPAND )
self.SetSizerAndFit(grilla)
self.Show(True)
if __name__ == "__main__":
app = wx.App()
frame = simpleapp_wx(None,-1,'Mi aplicacion')
app.MainLoop()
Ya tenemos tres widgets en nuestra aplicacion, todavia no hacen nada ni se ven bien
cuando redimensionamos la ventana, pero seguiremos mejorando nuestro programa.
class simpleapp_wx(wx.Frame):
def __init__(self,parent,id,title):
wx.Frame.__init__(self,parent,id,title)
self.parent = parent
self.initialize()
def initialize(self):
grilla = wx.GridBagSizer()
self.entrada = wx.TextCtrl(self,-1,value=u"Ingrese un texto:")
grilla.Add(self.entrada,(0,0),(1,1),wx.EXPAND)
boton = wx.Button(self,-1,label="Pulsame !")
grilla.Add(boton, (0,1))
self.etiqueta = wx.StaticText(self,-1,label=u'Hola !')
self.etiqueta.SetBackgroundColour(wx.BLUE)
self.etiqueta.SetForegroundColour(wx.WHITE)
grilla.Add( self.etiqueta, (1,0),(1,2), wx.EXPAND )
grilla.AddGrowableCol(0)
self.SetSizerAndFit(grilla)
self.Show(True)
if __name__ == "__main__":
app = wx.App()
frame = simpleapp_wx(None,-1,'Mi aplicacion')
app.MainLoop()
Ahora intente cambiar el tamaño de la ventana. El campo de texto y la etiqueta azul ahora
cambian de tamaño correctamente para adaptarse al tamaño de la ventana. Pero no se ve
tan bien cuando redimensionamos la ventana verticalmente.
class simpleapp_wx(wx.Frame):
def __init__(self,parent,id,title):
wx.Frame.__init__(self,parent,id,title)
self.parent = parent
self.initialize()
def initialize(self):
grilla = wx.GridBagSizer()
self.entrada = wx.TextCtrl(self,-1,value=u"Ingrese un texto:")
grilla.Add(self.entrada,(0,0),(1,1),wx.EXPAND)
boton = wx.Button(self,-1,label="Pulsame !")
grilla.Add(boton, (0,1))
self.etiqueta = wx.StaticText(self,-1,label=u'Hola !')
self.etiqueta.SetBackgroundColour(wx.BLUE)
self.etiqueta.SetForegroundColour(wx.WHITE)
grilla.Add( self.etiqueta, (1,0),(1,2), wx.EXPAND )
grilla.AddGrowableCol(0)
self.SetSizerAndFit(grilla)
self.SetSizeHints(-1,self.GetSize().y,-1,self.GetSize().y );
self.Show(True)
if __name__ == "__main__":
app = wx.App()
frame = simpleapp_wx(None,-1,'Mi aplicacion')
app.MainLoop()
class simpleapp_wx(wx.Frame):
def __init__(self,parent,id,title):
wx.Frame.__init__(self,parent,id,title)
self.parent = parent self.initialize()
def initialize(self):
grilla = wx.GridBagSizer()
self.entrada = wx.TextCtrl(self,-1,value=u"Ingrese un texto:", style=wx.TE_PROCESS
grilla.Add(self.entrada,(0,0),(1,1),wx.EXPAND)
self.entrada.Bind(wx.EVT_TEXT_ENTER, self.SiPulsaEnter)
boton = wx.Button(self,-1,label="Pulsame !")
grilla.Add(boton, (0,1))
boton.Bind (wx.EVT_BUTTON, self.SiCliqueaBoton)
self.etiqueta = wx.StaticText(self,-1,label=u'Hola !')
self.etiqueta.SetBackgroundColour(wx.BLUE)
self.etiqueta.SetForegroundColour(wx.WHITE)
grilla.Add(self.etiqueta, (1,0),(1,2), wx.EXPAND )
grilla.AddGrowableCol(0)
self.SetSizerAndFit(grilla)
self.SetSizeHints(-1,self.GetSize().y,-1,self.GetSize().y )
self.Show(True)
def SiCliqueaBoton(self,event):
self.etiqueta.SetLabel(self.entrada.GetValue() + "Cliqueo el boton!")
def SiPulsaEnter(self,event):
self.etiqueta.SetLabel(self.entrada.GetValue() + "Pulso enter!")
if __name__ == "__main__":
app = wx.App()
frame = simpleapp_wx(None,-1,'Mi aplicacion')
app.MainLoop()
class simpleapp_wx(wx.Frame):
def __init__(self,parent,id,title):
wx.Frame.__init__(self,parent,id,title)
self.parent = parent self.initialize()
def initialize(self):
grilla = wx.GridBagSizer()
self.entrada = wx.TextCtrl(self,-1,value=u"Ingrese un texto:", style=wx.TE_PROCESS
grilla.Add(self.entrada,(0,0),(1,1),wx.EXPAND)
self.entrada.Bind(wx.EVT_TEXT_ENTER, self.SiPulsaEnter)
boton = wx.Button(self,-1,label="Pulsame !")
grilla.Add(boton, (0,1))
boton.Bind (wx.EVT_BUTTON, self.SiCliqueaBoton)
self.etiqueta = wx.StaticText(self,-1,label=u'Hola !')
self.etiqueta.SetBackgroundColour(wx.BLUE)
self.etiqueta.SetForegroundColour(wx.WHITE)
grilla.Add(self.etiqueta, (1,0),(1,2), wx.EXPAND )
grilla.AddGrowableCol(0)
self.SetSizerAndFit(grilla)
self.SetSizeHints(-1,self.GetSize().y,-1,self.GetSize().y )
self.entrada.SetFocus()
self.entrada.SetSelection(-1,-1)
self.Show(True)
def SiCliqueaBoton(self,event):
self.etiqueta.SetLabel(self.entrada.GetValue() + "Cliqueo el boton!")
self.entrada.SetFocus()
self.entrada.SetSelection(-1,-1)
def SiPulsaEnter(self,event):
self.etiqueta.SetLabel(self.entrada.GetValue() + "Pulso enter!")
self.entrada.SetFocus()
self.entrada.SetSelection(-1,-1)
if __name__ == "__main__":
app = wx.App()
frame = simpleapp_wx(None,-1,'Mi aplicacion')
app.MainLoop()
Conclusiones
Bueno, eso es todo, espero que les sirva, si encuentran errores por favor me avisan asi lo
corrijo. El documento es de libre distribucion, solo me gustaria que se mantenga la
autoria, pero, si no lo quiere hacer tambien esta bien, la unica motivacion es compartir
conocimientos.
Si quieren profundizar en el uso de wxPython recomiendo los siguientes enlaces:
http://www.wxpython.org/onlinedocs.php
http://wiki.wxpython.org/
http://boa-constructor.sourceforge.net/