Si has llegado aquí mediante un buscador o por simple casualidad, te cuento que estas en la tercera parte de un tutorial que empieza AQUI.
En esta ultima entrega del tutorial, agregaremos un menú a la interface de ejemplo que venimos usando, y luego veremos como detectar los eventos del menú para reaccionar en consecuencia. Como lo venimos haciendo hasta ahora, seguiremos haciendo uso de wxFormBuilder.
Agregando un menú a nuestra interface con wxFormBuilder
En primer lugar, abriremos el proyecto que contiene la interface (archivo .fbp). De no tener el archivo del proyecto, pero si contar con el archivo .xrc, wxFormBuilder nos da la opción de importarlo; para lo cual creamos un proyecto vacío y seleccionamos la opción "Import XRC..." del menú "File". El Object Tree se vería así:
Para agregar el menú con wxFormBuilder, tenemos dos alternativas:
Opción 1: "Manual"
La primera opción, es la alternativa "más manual” de las dos.Un menú esta compuesto por una barra de menú (wx.MenuBar), que contiene los distintos menues propiamente dichos (wx.Menu), como ser "Archivo", "Editar", "Ver", etc., y dentro de estos, existen uno o mas ítems de menú (wx.MenuItem), como ser "Abrir", "Cerrar", "Imprimir", etc.; también pueden existir submenues, que en realidad no son mas que menues (wx.Menu) dentro de otro menú. Dicho esto, pasaremos a crearlo.
El menú que vamos a crear es muy sencillo. Para que veas las opciones que tendrá, a continuación te muestro una imagen:
Para crear este menú, y teniendo en mente lo dicho antes, lo primero que crearemos será la barra que contendrá el menú (wx.MenuBar); para lo que seleccionamos el Frame en el Object Tree, y pulsamos el botón "wx.MenuBar" que encontramos en la solapa "Menu/ToolBar" de la paleta de componentes:
Tras agregar la barra de menú, el Editor se vería así:

Como segundo paso, vamos a agregar a la barra de menú, el menú "Opciones". Para agregarlo tan solo debemos clickear el botón wx.Menu en la misma solapa desde la que agregamos la barra. Una vez agregado, editamos su propiedad label con el texto "Opciones".

Por último, agregamos dos ítems pulsando dos veces el botón wxMenuItem en la barra de componentes, y modificamos la propiedad label de ambos, el primero con el valor "Mostrar bienvenida" y el segundo con el valor "Salir".

Con esto tendríamos nuestro menú terminado. El Object Tree se ve así:

Si ejecutamos la ventana pulsando F5, veremos lo siguiente:
Puedes apreciar que el botón "Cancelar" quedo "cortado"; para evitar esto moveremos el menú al inicio dentro del "Objet Tree". Para mover un ítem en forma vertical dentro del Object Tree, lo seleccionamos y pulsamos la tecla ALT y la tecla "arriba" o "abajo" según corresponda, en nuestro caso pulsamos ALT + "Arriba", con lo cual el Object Tree quedaría así.
Si ahora ejecutamos la ventana, la veríamos correctamente:
Ahora les muestro la misma captura, pero con el menú desplegado:
IMPORTANTE:La solución de mover el menú a la parte superior dentro del Object Tree, por ahora te pido que lo tomes "tal cual te lo digo", en otra oportunidad cuando haga un tutorial especifico sobre menues en wxPython, hablaremos mas en detalle.
Opción 2: "Asistida"
En este método, usaremos una herramienta de wxFormBuilder, que nos permite editar el menú en forma mas asistida. Para invocarla, pulsamos el botón derecho del mouse sobre el Frame en el Object Tree y elegimos la opción Menu Editor...
El editor de menú lo puedes ver en la siguiente imagen:

Veamos paso a paso como crear el mismo menú que antes, pero ahora usando el Editor de menú:
A diferencia del método anterior, aquí no tenemos que agregar la barra que contendrá el menú (wx.MenuBar), ya que el asistente lo hará por nosotros, así que simplemente empezamos agregando el menú "Opciones" (wx.Menu). Para agregar este menú, tan solo debemos escribir el nombre del mismo (en este caso “Opciones” ) en la caja de texto junto a la etiqueta "label" y pulsar el botón "Add":

Tras pulsar el botón "Add", veremos que en el panel de la izquierda del Menu Editor se agregara una fila que representa el nuevo menú:

Al escribir el valor de la propiedad "label", el asistente completará las propiedades "Id" y "Name" automáticamente, pero de todos modos, podemos editarlos en forma manual.
Ahora repetimos el procedimiento anterior, pera con el texto "Mostrar bienvenida" en la propiedad label. Una vez agregado este item de menú, la lista del panel izquierdo del Menu Editor quedara así:

Si bien el ítem ha sido agregado, aun no hemos indicado que este ultimo es un wx.MenuItem; para que wxFomBuilder lo reconozca como tal, pulsamos el botón que tiene el signo mayor (>).

Al pulsar el botón “>”, el ítem que tengamos seleccionado se convierte en el hijo del ítem que tiene en la fila que se encuentre arriba de el.
Ya sólo nos queda agregar el otro ítem de menú (“Salir”), así que procedemos a repetir los mismo pasos que hicimos para agregar el ítem de menú “Mostrar Bienvenida”, pero ahora con el label "Salir". Luego de agregarlo, el Menu Editor quedaría así:

Listo, de este modo tenemos el menu terminado haciendo uso del Editor de Menú de wxFormBuilder. Una vez mas, no quise entrar en detalle sobre las características de este Editor, ya que eso lo veremos en otro tutorial más especifico sobre el uso de Menues.
En mi caso, para agregar el menú, opte por la opción asistida. Ya sea que usemos el meo todo 1 (“Manual”) o el método 2 (”Asistido”), debemos exportar el archivo XRC como ya vimos antes, y luego pasamos nuevamente al código de nuestra aplicación, para darle uso a nuestras dos opciones de menú.
Manejando los eventos de nuestro menú
Para refrescar la memoria, a continuación te muestro el código de nuestra aplicación hasta el momento:import wxEn primer lugar, enlazaremos el ítem de menú "Mostrar bienvenida" con el mismo manejador de evento que teníamos creado para el botón "Aceptar". Esto de enlazar un mismo manejador de evento con varios widgets es muy común, sobre todo lo podemos ver en el caso que una misma función, la ejecutamos desde una opción de menú y desde un botón de una barra de herramientas (Por ej: las opciones Cortar, Copiar, Pegar, en general la encontramos como items del menú Editar y como botones de una barra de herramientas).
from wx import xrc
class MiAplicacion(wx.App):
def OnInit(self):
self.res = xrc.XmlResource('gui_tutorial.xrc')
self.frame = self.res.LoadFrame(None, 'MyFrame')
self.botonAceptar = xrc.XRCCTRL(self.frame, 'm_button1')
self.frame.Bind(wx.EVT_BUTTON, self.mostrar_bienvenida, self.botonAceptar)
self.botonCancelar = xrc.XRCCTRL(self.frame, 'm_button2')
self.frame.Bind(wx.EVT_BUTTON, self.salir, self.botonCancelar)
self.frame.Show()
return True
def mostrar_bienvenida(self, event):
wx.MessageBox('Bienvenido!')
def salir(self, event):
self.frame.Close()
if __name__ == '__main__':
app = MiAplicacion()
app.MainLoop()
Para hacer el enlace haremos uso (nuevamente) de la la función Bind(). Hasta el momento hemos usado la función xrc.XRCCTRL() para obtener una referencia al widget del que queremos captar el evento, pero esto no nos servirá para el caso de los menues. La función xrc.XRCCTRL() sólo puede retornar objetos que deriven de la clase wxWindow, pero cuando esto no se cumple, como es el caso de la clase wxMenuItem, deberemos hacer uso de la función xrc.XRCID(), la cual nos devuelve el ID del widget que tenga el nombre que le pasamos como parámetro y luego usar este ID en el parámetro id de la función Bind(). El código para enlazar el ítem de menú "Mostrar bienvenida" con la función mostrar_bienvenida() será el siguiente:
self.frame.Bind(wx.EVT_MENU, self.mostrar_bienvenida, id=xrc.XRCID('mostrarBienvenida'))
Teniendo en cuenta esto, sólo me queda comentarte que el Event Binder para capturar la pulsación de un ítem de menú es wx.EVT_MENU, es por esto que el valor del primer parámetro es justamente este.
Para enlazar el segundo ítem de menú ("Salir") el código sería el siguiente:
self.frame.Bind(wx.EVT_MENU, self.salir, id=xrc.XRCID('salir'))
Si ahora juntamos todo el código, nos quedaría así:
import wx
from wx import xrc
class MiAplicacion(wx.App):
def OnInit(self):
self.res = xrc.XmlResource('gui_tutorial.xrc')
self.frame = self.res.LoadFrame(None, 'MyFrame')
self.botonAceptar = xrc.XRCCTRL(self.frame, 'm_button1')
self.frame.Bind(wx.EVT_BUTTON, self.mostrar_bienvenida, self.botonAceptar)
self.botonCancelar = xrc.XRCCTRL(self.frame, 'm_button2')
self.frame.Bind(wx.EVT_BUTTON, self.salir, self.botonCancelar)
self.frame.Bind(wx.EVT_MENU, self.mostrar_bienvenida, id=xrc.XRCID('mostrarBienvenida'))
self.frame.Bind(wx.EVT_MENU, self.salir, id=xrc.XRCID('salir'))
self.frame.Show()
return True
def mostrar_bienvenida(self, event):
wx.MessageBox('Bienvenido!')
def salir(self, event):
self.frame.Close()
if __name__ == '__main__':
app = MiAplicacion()
app.MainLoop()
Si ejecutamos el programa, ahora podemos pulsar el botón "Aceptar" o seleccionar la opción "Mostrar bienvenida" del menú "Opciones", y obtendremos el mensaje "Bienvenido!"; y si pulsamos el botón "Cancelar" o elegimos la opción "Salir" del menú "Opciones", el programa finalizará.
Con esto doy por terminado este tutorial. Como siempre, apelo a ustedes para que si consideran necesario agregar, modificar, eliminar y/o corregir algo, lo comenten así entre todos vamos generando cada vez mas material en nuestro idioma sobre wxPython.
Saludos!








































