如何将子菜单项添加到 wxPython 中的弹出菜单项?

问题描述

我想向现有的弹出菜单添加一些子菜单项。我找到了几个关于如何为标准菜单创建子菜单的示例,但没有关于为弹出菜单创建子菜单的示例。

我尝试将与标准菜单相同的逻辑应用于弹出菜单,但未能正确执行(同时我在创建带有子菜单的标准菜单时没有遇到任何问题)。

在如下代码的一部分中,如何添加菜单

# ...

class ButtonContext(wx.Menu):
    def __init__(self,parent):
        super(ButtonContext,self).__init__()
        self.parent = parent
 
        button_popup = wx.MenuItem(self,wx.ID_ANY,'test popup')
        self.Append(button_popup)
        self.Bind(wx.EVT_MENU,self.button_action,button_popup)
 
    def button_action(self,event):
        event.Skip()

# ...

解决方法

这会起作用,实际上弹出菜单基于 wx.Menu 类,因此逻辑和行为是相同的

class ButtonContext(wx.Menu):
    def __init__(self,parent):
        super(ButtonContext,self).__init__()
        self.parent = parent

        button_popup = wx.MenuItem(self,wx.ID_ANY,'test popup')
        submenu_popup = wx.Menu()
        submenu_button_popup = wx.MenuItem(self,'test submenu popup')
        submenu_popup.Append(submenu_button_popup)
        self.AppendSubMenu(submenu_popup,"submenu")
        self.Append(button_popup)
        self.Bind(wx.EVT_MENU,self.button_action,button_popup)
,

只是为了说明 SetSubMenu(menu) 方法,该方法也可用于在此实例中创建子菜单。

import wx

class MyFrame(wx.Frame):
    def __init__(self,*args,**kwds):
        kwds["style"] = kwds.get("style",0) | wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self,**kwds)
        self.SetSize((400,300))
        self.SetTitle("test frame")

        sizer_0 = wx.BoxSizer(wx.HORIZONTAL)
        self.window_1 = wx.SplitterWindow(self,wx.ID_ANY)
        self.window_1.SetMinimumPaneSize(20)
        sizer_0.Add(self.window_1,1,wx.EXPAND,0)

        self.pane_1 = wx.Panel(self.window_1,wx.ID_ANY)
        sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
        self.pane_2 = wx.Panel(self.window_1,wx.ID_ANY)
        sizer_2 = wx.BoxSizer(wx.HORIZONTAL)

        self.button = wx.Button(self.pane_2,"test button")
        sizer_2.Add(self.button,0)

        self.pane_1.SetSizer(sizer_1)
        self.pane_2.SetSizer(sizer_2)
        self.window_1.SplitVertically(self.pane_1,self.pane_2)
        self.SetSizer(sizer_0)
        self.Layout()

        self.Bind(wx.EVT_CONTEXT_MENU,self.OnButtonContextMenu,self.button)
        self.Show()

    def OnButtonContextMenu(self,event):
        self.PopupMenu(ButtonContext(self))

class ButtonContext(wx.Menu):
    def __init__(self,self).__init__()
        self.parent = parent
 
        button_popup = wx.MenuItem(self,'test popup')
        self.Append(button_popup)        
        submenu = wx.Menu()
        submenu1 = wx.MenuItem(submenu,'Submenu 1')
        submenu2 = wx.MenuItem(submenu,'Submenu 2')
        submenu3 = wx.MenuItem(submenu,'Submenu 3')
        submenu.Append(submenu1)
        submenu.Append(submenu2)
        submenu.Append(submenu3)
        button_popup2 = wx.MenuItem(self,'A sub menu')
        button_popup2.SetSubMenu(submenu)
        self.Append(button_popup2)
        self.Bind(wx.EVT_MENU,button_popup)
        self.Bind(wx.EVT_MENU,self.submenu1_action,submenu1)
 
    def button_action(self,event):
        print("Test Menu Button")
        event.Skip()

    def submenu1_action(self,event):
        print("Submenu 1")
        event.Skip()
        
class MyApp(wx.App):
    def OnInit(self):
        self.frame = MyFrame(None,"")
        return True

if __name__ == "__main__":
    app = MyApp()
    app.MainLoop()

enter image description here