Как добавить элемент подменю к пункту всплывающего меню в wxPython?

#python #wxpython

#python #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()

# ...
 

Ответ №1:

Это будет работать, на самом деле всплывающие меню основаны на 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, wx.ID_ANY, '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)
 

Комментарии:

1. Ну, можно сказать, что это работает таким образом, но не совсем так, как я себе представлял. Код «как есть» выдает Menu.AppendSubMenu(): not enough arguments ошибку, которую можно решить, добавив текстовую метку в соответствии с docs.wxpython.org/wx.Menu.html#wx.Menu . AppendSubMenu ; однако это также означает, что для этой текстовой метки создается новый элемент меню (к которому привязано подменю). Должен ли я понимать, что это единственный способ сделать это? Я был заинтересован в сохранении «оригинального» пункта меню, так как в моем реальном коде с ним также связан значок растрового изображения (но не катастрофическая проблема, если в противном случае).

2. извините, я забыл это, теперь я отредактировал, это должно работать, и да, единственный способ использовать подменю — добавить wx. Меню как элемент меню с AppendSubMenu()

3. Существует также SetSubMenu(menu) для меню, которое было определено отдельно.

Ответ №2:

Просто чтобы проиллюстрировать 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, *args, **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, wx.ID_ANY, "test button")
        sizer_2.Add(self.button, 0, 0, 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, parent):
        super(ButtonContext, self).__init__()
        self.parent = parent
 
        button_popup = wx.MenuItem(self, wx.ID_ANY, 'test popup')
        self.Append(button_popup)        
        submenu = wx.Menu()
        submenu1 = wx.MenuItem(submenu, wx.ID_ANY, 'Submenu 1')
        submenu2 = wx.MenuItem(submenu, wx.ID_ANY, 'Submenu 2')
        submenu3 = wx.MenuItem(submenu, wx.ID_ANY, 'Submenu 3')
        submenu.Append(submenu1)
        submenu.Append(submenu2)
        submenu.Append(submenu3)
        button_popup2 = wx.MenuItem(self, wx.ID_ANY, 'A sub menu')
        button_popup2.SetSubMenu(submenu)
        self.Append(button_popup2)
        self.Bind(wx.EVT_MENU, self.button_action, 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, wx.ID_ANY, "")
        return True

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

введите описание изображения здесь