为什么我不能直接将事件绑定到Windows中的wx.Menu?

时间:2012-12-03 06:32:11

标签: python wxpython

我有一个应用程序,允许一些控制器更改主菜单栏的布局。我通过将主菜单栏传递给控制器​​来执行此操作,然后控制器向其添加一些菜单。我的问题是将菜单点击事件绑定到那些添加的菜单。理论上这很容易:

def bind_main_menu_bar(self, main_menu_bar):
    self.main_menu_bar = main_menu_bar

    edit_menu = shared.create_menu([
        (const.ID_UNDO, self.LABEL_UNDO_EMPTY),
        (const.ID_REDO, self.LABEL_REDO_EMPTY),
        (),
        (const.ID_VALIDATE_ADDRESSES, 'Validate selected addresses'),
        (const.ID_VALIDATE_ALL_ADDRESSES, 'Validate all addresses'),
    ])
    edit_menu.Bind(wx.EVT_MENU, self.on_menu)
    edit_menu.Bind(wx.EVT_UPDATE_UI, self.on_menu_update)

    main_menu_bar.Insert(1, edit_menu, 'Edit')

这在OSX中非常有效,但在Windows中,只有wx.EVT_MENU事件在将事件直接绑定到edit_menu菜单时才有效。换句话说,永远不会触发wx.EVT_UPDATE_UI事件处理程序。我也尝试过绑定EVT_MENU_OPENEVT_MENU_CLOSEEVT_MENU_HIGHLIGHT,但它们都不起作用。当我将它们绑定到顶级框架时它们都可以工作,但是没有办法将事件处理程序限制为只有edit_menu菜单。

这是一个错误,还是有什么我忽略的?此外,任何人都可以针对我的问题找到解决方法吗?


我在Window 8上使用wxPython 2.9(dev)。

2 个答案:

答案 0 :(得分:4)

Mike是对的,避免使用明确的ID - 而且您不需要它们(有关详细信息,请参阅wxPython Style guide in the wiki)。

菜单项不是常规Windows,所以你不能用它们做正常的事件绑定 - 太糟糕了。

但是,将事件绑定到框架时,可以指定事件的来源。我通常用于绑定菜单事件的习惯用语:

FileMenu = wx.Menu()
item = FileMenu.Append(wx.ID_EXIT, "&Quit")
self.Bind(wx.EVT_MENU, self.OnQuit, item)

在这种情况下,selfFrame - 所以你说:将EVT_MENU绑定到框架,调用self.OnQuit作为回调,但仅限绑定来自此特定菜单项的事件。

当你进行动态绑定时,这是更加丑陋的,但它应该可以工作。

请注意,在此示例中,我使用的是ID - 该规则的例外情况是使用标准ID(例如wx.ID-EXITwx.ID_HELP)很不错,因为wx可以在各种平台上“做正确的事”(比如OS-X上应用菜单的菜单更多)。

答案 1 :(得分:1)

我很确定你应该将菜单事件绑定到框架,而不是菜单项本身。试试看,看看它是否有效。