我有一个应用程序,允许一些控制器更改主菜单栏的布局。我通过将主菜单栏传递给控制器来执行此操作,然后控制器向其添加一些菜单。我的问题是将菜单点击事件绑定到那些添加的菜单。理论上这很容易:
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_OPEN
,EVT_MENU_CLOSE
和EVT_MENU_HIGHLIGHT
,但它们都不起作用。当我将它们绑定到顶级框架时它们都可以工作,但是没有办法将事件处理程序限制为只有edit_menu
菜单。
这是一个错误,还是有什么我忽略的?此外,任何人都可以针对我的问题找到解决方法吗?
我在Window 8上使用wxPython 2.9(dev)。
答案 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)
在这种情况下,self
是Frame
- 所以你说:将EVT_MENU
绑定到框架,调用self.OnQuit
作为回调,但仅限绑定来自此特定菜单项的事件。
当你进行动态绑定时,这是更加丑陋的,但它应该可以工作。
请注意,在此示例中,我使用的是ID - 该规则的例外情况是使用标准ID(例如wx.ID-EXIT
,wx.ID_HELP
)很不错,因为wx
可以在各种平台上“做正确的事”(比如OS-X上应用菜单的菜单更多)。
答案 1 :(得分:1)
我很确定你应该将菜单事件绑定到框架,而不是菜单项本身。试试看,看看它是否有效。