0

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

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永远不会触发事件处理程序。我也尝试过 binding EVT_MENU_OPENEVT_MENU_CLOSEEVT_MENU_HIGHLIGHT它们都不起作用。当我将它们绑定到顶级框架时,它们都可以工作,但是没有办法将事件处理程序限制为仅edit_menu菜单。

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


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

4

2 回答 2

4

Mike 是对的,避免使用显式 ID——而且您不需要它们(有关详细信息,请参阅wiki 中的 wxPython 样式指南)。

菜单项不是常规的 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-EXIT, wx.ID_HELP)很好,因为这样wx可以在各种平台上“做正确的事”(例如应用程序的更多菜单OS-X 上的菜单)。

于 2012-12-04T00:08:32.183 回答
1

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

于 2012-12-03T14:38:10.263 回答