AUI error: any pushed event handlers must have been removed

I’m trying to work with AUI and keep getting the following error…

wx._core.wxAssertionError: C++ assertion “GetEventHandler() == this” failed at
/usr/local/miniconda/conda-bld/wxpython_1585592756259/work/ext/wxWidgets/src/common/wincmn.cpp(478)
in ~wxWindowBase(): any pushed event handlers must have been removed

I’ve reduced my code down to a simple program that reproduces the error (below). Please note that the “MyFrame” definition is auto-generated by wxFormBuilder, so I’m only supposed to modify that through subclasses. As I’m on OSX, I’m using the “pythonw” interpreter.

I’ve found references to this error on the internet, but none of the solutions seem to match my case.

Where am I going wrong?

Thanks,
Eric

import wx
import wx.xrc
import wx.aui


# Code for the frame was auto-generated by wxFormBuilder

class MyFrame1(wx.Frame):

    def __init__(self, parent):
        wx.Frame.__init__(self, parent, id=wx.ID_ANY, title=wx.EmptyString, pos=wx.DefaultPosition,
                          size=wx.Size(870, 700), style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL)

        self.SetSizeHints(wx.DefaultSize, wx.DefaultSize)
        self.m_mgr = wx.aui.AuiManager()
        self.m_mgr.SetManagedWindow(self)
        self.m_mgr.SetFlags(wx.aui.AUI_MGR_DEFAULT)

        self.m_mgr.Update()
        self.Centre(wx.BOTH)

    def __del__(self):
        self.m_mgr.UnInit()


class MyApp(wx.App):

    def OnInit(self):
        self.frame = MyFrame1(None)
        self.SetTopWindow(self.frame)
        self.frame.Show(True)
        return True

# -------------------------------------------------------------------------------

def main():
    app = MyApp(False)
    app.MainLoop()

# -------------------------------------------------------------------------------

if __name__ == "__main__":
    main()






The __del__ does not happen soon enough, (and may not happen at all before the GUI elements are gone) so you should add a handler for EVT_CLOSE and do the UnInit there.

P.S. Try putting some print statements in your EVT_CLOSE handler, in __del__ and after MainLoop returns to see the order that they happen.

You’re a genius. Works perfectly! Here are the modified code and the print results…

import wx
import wx.xrc
import wx.aui

# Code for the frame was auto-generated by wxFormBuilder

class MyFrame1(wx.Frame):

    def __init__(self, parent):
        wx.Frame.__init__(self, parent, id=wx.ID_ANY, title=wx.EmptyString, pos=wx.DefaultPosition,
                          size=wx.Size(870, 700), style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL)

        self.SetSizeHints(wx.DefaultSize, wx.DefaultSize)
        self.m_mgr = wx.aui.AuiManager()
        self.m_mgr.SetManagedWindow(self)
        self.m_mgr.SetFlags(wx.aui.AUI_MGR_DEFAULT)

        self.m_mgr.Update()
        self.Centre(wx.BOTH)

        # added
        self.Bind(wx.EVT_CLOSE, self.OnClose)

    def __del__(self):
        print ("at __del__")
        #self.m_mgr.UnInit()               # removed
        pass

    def OnClose(self, event):
        print ("at OnClose")
        self.m_mgr.UnInit()             # added
        event.Skip()


class MyApp(wx.App):

    def OnInit(self):
        self.frame = MyFrame1(None)
        self.SetTopWindow(self.frame)
        self.frame.Show(True)
        return True

# -------------------------------------------------------------------------------

def main():
    app = MyApp(False)
    app.MainLoop()
    print ("exited MainLoop")

# -------------------------------------------------------------------------------

if __name__ == "__main__":
    main()

at OnClose
exited MainLoop
at del