martes 1 de marzo de 2011

Pasar parámetros entre frames en wxPython

Hola. En este artículo vamos a ver una forma muy sencilla de pasar parámetros entre 2 frames en wxPython, uno padre de otro. El paso de mensajes ó parámetros entre objetos se puede hacer de varias formas, siendo la que vamos a ver una de las más fáciles.

Aunque lo vamos a ver con un ejemplo (esto es, código), no está de más explicar el funcionamiento. La aplicación es un fichero .py donde tenemos una aplicación wxPython, que instancia una clase (frame_principal). Dicha clase, al hacer click en un botón instancia una segunda clase (frame_secundario). Cuando se introducen datos en el frame_secundario (objeto) y se hace click en un botón, se devuelve dicha información al frame_principal, que lo muestra. Es decir, se introducen datos en un frame y los devuelve al frame maestro desde que fue instanciado (llamado).

¿Cómo se ha hecho? La cuestión es que cuando se instancia el frame_secundario en el frame_principal, se le pasa como parámetro una referencia de él mismo. En frame_secundario se crea un atributo (self.padre), que contiene la referencia al frame padre en donde fue creado.

Este ejemplo se ha realizado en Linux Ubuntu y el editor joe. El código es el siguiente:


# -*- coding: utf-8 -*-
# El viaje del navegante.
# Ejemplo de paso de parámetros entre 2 frames en wxPython.

# Importamos las wx
import wx

# Creamos una clase frame que pide un dato.
class frame_secundario(wx.Frame):
  def __init__(self, parent):
    # Este es el constructor. Darse cuenta que se pasa como
    # parámetro parent, esto es, la referencia del frame que instancia
    # a esta clase. La guardamos.
    self.padre = parent
    # Llamamos al constructor de la clase de la que hereda.
    wx.Frame.__init__(self, None, -1, title = "Introduce un valor")
    # Creamos un sizer horizontal.
    sizer = wx.BoxSizer( wx.HORIZONTAL )
    # Creamos una caja de texto.
    self.caja_texto = wx.TextCtrl(self, -1)
    # Creamos un botón.
    self.boton = wx.Button(self, -1,"ACEPTAR")
    # Añadimos al sizer la caja y el botón.
    sizer.Add(self.caja_texto, 0, wx.ALL, 5)
    sizer.Add(self.boton, 0, wx.ALL, 5)
    # Incluimos el sizer en el frame.
    self.SetSizer(sizer)
    # Creamos el binding. Cuando se haga click en el
    # botón se lanzará el manejador de eventos correspondiente.
    self.boton.Bind(wx.EVT_BUTTON, self.OnClickBoton)

  # Manejador de eventos.   
  def OnClickBoton(self, event):
    # Obtenemos datos de la caja de texto.
    dato = self.caja_texto.GetValue()
    # Podríamos escribir directamente en el objeto
    # que se desease.
    self.padre.caja_texto.SetValue(dato)
    # Nos vamos.
    self.Destroy()
  
# Creamos la clase de la ventana principal.   
class frame_principal(wx.Frame):
  def __init__(self):
    # Constructor. Llamamos al constructor de la clase wx.Frame.
    wx.Frame.__init__(self, None, -1, title = 'Ventana Principal')
    # Creamos un sizer horizontal.
    sizer = wx.BoxSizer( wx.HORIZONTAL )
    # Creamos un botón.
    self.boton = wx.Button(self, -1, "Crear Frame Secundario")
    # Creamos una caja de texto de solo lectura.
    self.caja_texto = wx.TextCtrl(self, -1, style = wx.TE_READONLY)
    # Añadimos al sizer la caja y el botón.
    sizer.Add(self.boton, 0, wx.ALL, 5)
    sizer.Add(self.caja_texto, 0, wx.ALL, 5)
    # Asociamos el sizer al frame.
    self.SetSizer(sizer)
    # Creamos el binding. Cuando se haga click en el
    # botón se lanzará el manejador de eventos correspondiente.
    self.boton.Bind(wx.EVT_BUTTON, self.OnClickBoton)
     
  # Manejador de eventos.   
  def OnClickBoton(self, event):
    # Si se hace click se crea una instancia del frame_secundario.
    frame = frame_secundario(self)
    # Mostramos.
    frame.Show()
      
# Creamos una aplicación wxPython.
aplicacion = wx.PySimpleApp()
# Instanciamos el frame principal.
frame = frame_principal()
# Y por supuesto, no olvidar mostrarlo.
frame.Show()
# Esperamos a capturar eventos.
aplicacion.MainLoop()
   

El código está muy comentado, pero volvemos a analizarlo. Se crea una aplicación wxPython, que instancia la clase frame_principal.


Si hacemos click en el botón "Crear Frame Secundario" se instancia la clase frame_secundario, creando un segundo frame:



Incluimos un texto en la caja de texto, PYTHON!!!, y hacemos click en el botón Aceptar. 


Tal como se aprecia en el código, se envía el dato al frame padre y se destruye la instancia del frame_secundario.Y el resultado es:






En el código se ha resaltado en verde el paso de la referencia del frame padre. 


Saludos.

3 comentarios:

  1. Fantastico, muchas gracias!!

    ResponderSuprimir
  2. Muy útil para el que empieza.
    Buen ejemplo.
    Funciona perfectamente.

    ResponderSuprimir
  3. Hola José Luis, me alegro que te sirva.

    Saludos.

    ResponderSuprimir