在wxPython中的另一个模块中绑定菜单事件处理程序

时间:2018-04-17 13:15:18

标签: python class wxpython

我正在使用wxPython(python3)为框架构建菜单。 我想将main.py与menus.py分开 - 将这两个分开的文件分开,以便将代码组织成更小的部分。

我需要能够将控制权从menus.py传递回main.py. 特别是,我需要为菜单项(在menus.py中)绑定的事件的处理程序将驻留在main.py中,或者,在menus.py中具有处理程序,但在main.py中引用对象(用于例如,关闭()“退出”菜单项的应用程序。

这是我到目前为止所做的,我尝试了两种方法都没有成功。这是如何实现的?

main.py

import wx
import menus

class MainFrame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "My App Title", size=(1200, 800))
        self.panel = wx.Panel(self, wx.ID_ANY)

        mainMenu = menus.MainMenu()
        mainMenu.build_main_menu(self)


    def onExit(self):
        self.Close()


if __name__ == "__main__":
    app = wx.App(False)
    frame = MainFrame()
    frame.Show()
    app.MainLoop()

menus.py

from wx import Menu, MenuBar, MenuEvent, MenuItem, Frame, EVT_MENU

class MainMenu(object):
    def build_main_menu(self, frame):

        self.fileMenu = Menu()
        exitMenuItem = self.fileMenu.Append(101, "E&xit", "Close the application")


        menuBar = MenuBar()
        menuBar.Append(self.fileMenu, "&File")
        frame.Bind(EVT_MENU, MainFrame.onExit(frame), exitMenuItem)
        frame.SetMenuBar(menuBar)

        return self

1 个答案:

答案 0 :(得分:0)

你真的很亲密,但就在那里。对于这种事情,没有必要将菜单创建代码包装在一个类中,所以我将其更改为一个函数。这是menu.py

from wx import Menu, MenuBar, MenuEvent, MenuItem, Frame, EVT_MENU


def build_main_menu(frame):

    fileMenu = Menu()
    exitMenuItem = fileMenu.Append(101, "E&xit", "Close the application")

    menuBar = MenuBar()
    menuBar.Append(fileMenu, "&File")
    frame.Bind(EVT_MENU, frame.onExit, exitMenuItem)
    frame.SetMenuBar(menuBar)

请注意,您需要使用onExit实例调用frame,而不是尝试通过您尚未导入的类(MainFrame)调用它。你也可以在绑定操作中调用事件处理程序。按下按钮时会调用它。

接下来,我更新了您的main.py

import wx
import menus

class MainFrame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "My App Title", size=(1200, 800))
        self.panel = wx.Panel(self, wx.ID_ANY)

        mainMenu = menus.build_main_menu(self)

    def onExit(self, event):
        self.Close()


if __name__ == "__main__":
    app = wx.App(False)
    frame = MainFrame()
    frame.Show()
    app.MainLoop()

这里有两处变化。首先,我们不需要创建菜单模块类的实例,因为不再有类。其次,事件处理程序有两个参数:selfevent

现在有效!