Skip to content

"wrapped C/C++ object of type Menu has been deleted" error when adding/removing submenu #2848

@qazmlpok

Description

@qazmlpok

Operating system: Ubuntu 24.04.3 LTS
wxPython version & source: '4.2.3 gtk3 (phoenix) wxWidgets 3.2.7'
Python version & source: Python 3.12.3 (main, Jan 8 2026, 11:30:50) [GCC 13.3.0] on linux

I'm running this on Linux but also reproduced the issue on my Windows machine. I believe it's running the same version of wxPython

Description of the problem:

Calling Remove on a submenu and attempting to re-add it or interact with it in any way is giving an error: RuntimeError: wrapped C/C++ object of type Menu has been deleted. The below program illustrates the issue. Click on the 'Add' button, then 'Remove', then 'Add' again. The buttons are necessary because the deletion appears to happen sometime after Remove() is called, not as part of the call to remove. I don't think this could be Python's GC because it should still have a reference to the submenu.

The documentation for Remove explicitly states "doesn’t delete the associated C++ object.", so I'm pretty sure this is a bug. I haven't tried it with other menu items.

Code Example (click to expand)
#!/usr/bin/env python3

import wx

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

        self.attached = False

        # Menu Bar
        self.frame_menubar = wx.MenuBar()
        self.TopMenu = wx.Menu()
        self.frame_menubar.Append(self.TopMenu, "item")
        self.SetMenuBar(self.frame_menubar)

        self.SubMenu = wx.Menu()
        self.SubMenu.Append(wx.NewId(), 'Sub Item')
        # Menu Bar end

        self.panel_1 = wx.Panel(self, wx.ID_ANY)

        sizer_1 = wx.BoxSizer(wx.VERTICAL)

        sizer_1.Add((0, 0), 0, 0, 0)


        btn_add = wx.Button(self.panel_1, wx.ID_ANY, "Add")
        btn_remove = wx.Button(self.panel_1, wx.ID_ANY, "Remove")
        self.Bind(wx.EVT_BUTTON, self.on_attach, btn_add)
        self.Bind(wx.EVT_BUTTON, self.on_detach, btn_remove)
        sizer_1.Add(btn_add)
        sizer_1.Add(btn_remove)


        self.panel_1.SetSizer(sizer_1)

        self.Layout()
        # end wxGlade
    def on_attach(self, e):
        if not self.attached:
            self.attached = True
            self.TopMenu.AppendSubMenu(self.SubMenu, "Submenu")
    def on_detach(self, e):
        if self.attached:
            self.attached = False
            while self.TopMenu.GetMenuItemCount() > 0:
                item = self.TopMenu.FindItemByPosition(0)
                self.TopMenu.Remove(item)

# end of class MyFrame

class MyApp(wx.App):
    def OnInit(self):
        self.frame = MyFrame(None, wx.ID_ANY, "")
        self.SetTopWindow(self.frame)
        self.frame.Show()
        return True

# end of class MyApp

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions