我想出了一个非常干净的方法来做到这一点。首先,我创建了我的“基本”主菜单栏,其中包含文件和帮助菜单项。然后我定义了一个类EditorPanel
而不是它的子类,wx.Panel
并定义了方法bind_main_menu_bar
和release_main_menu_bar
。这些方法中的第一个在面板获得焦点时接收主菜单栏,并向其中添加一些项目。这是我的实现之一:
def bind_main_menu_bar(self, main_menu_bar):
main_frame = wx.GetApp().GetTopWindow()
self.main_menu_bar = main_menu_bar
# Create the edit menu.
self.edit_menu = edit_menu = shared.create_menu([
(const.ID_UNDO, self.LABEL_UNDO_EMPTY),
(const.ID_REDO, self.LABEL_REDO_EMPTY)
])
# Create the tools menu.
self.tools_menu = tools_menu = shared.create_menu([
(const.ID_SELECT_ADDRESS_COLUMNS, 'Select address columns...'),
(),
(const.ID_VALIDATE_ADDRESSES, 'Validate selected addresses'),
(const.ID_VALIDATE_ALL_ADDRESSES, 'Validate all addresses')
])
# Bind some menu event handlers to the main frame.
main_frame.Bind(wx.EVT_MENU, self.on_menu)
main_frame.Bind(wx.EVT_UPDATE_UI, self.on_menu_update)
# Insert the new menus into the main menu bar.
main_menu_bar.Insert(1, edit_menu, 'Edit')
main_menu_bar.Insert(2, tools_menu, 'Tools')
现在,当打开该编辑器面板时,主菜单会收到一个 Edit 菜单和一个绑定到事件处理程序的 Tools 菜单EditorPanel
,这非常方便。当编辑器失去焦点时,将release_main_menu_bar
调用该方法,该方法应将主菜单栏恢复到其原始状态。这是上面代码的对应部分:
def release_main_menu_bar(self):
main_frame = wx.GetApp().GetTopWindow()
# Unbind the menu event handlers from the main frame.
main_frame.Unbind(wx.EVT_MENU, handler=self.on_menu)
main_frame.Unbind(wx.EVT_UPDATE_UI, handler=self.on_menu_update)
# Remove the edit and tools menu from the main menu bar.
self.main_menu_bar.Remove(1)
self.main_menu_bar.Remove(1)
# Reset the fields used for the menu.
self.edit_menu = None
self.tools_menu = None
self.main_menu_bar = None
所以每个想要编辑主菜单的编辑器只需要继承这两个方法,他们就可以完全控制。主框架将监视用户何时在编辑器之间切换并相应地调用方法。最大的问题是要弄清楚编辑器面板何时接收和失去焦点,这是我的另一个问题的主题:如何监控 wx.Panel 何时接收和失去焦点?