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.

5 comentarios:

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

    ResponderEliminar
  2. Hola José Luis, me alegro que te sirva.

    Saludos.

    ResponderEliminar
  3. Me podrías ayudar quiero que un frame se despliegue embebido dentro del mismo frame principal es decir una área dentro del frame principal

    ResponderEliminar