About dict of wx.Frame

Hi
My frame is four children.When I destroy one of them, I still find it in dict
of my frame.Why?

class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="TextCtrl Demo",size=(500,300))
        self.Centre()
        self.hotkey = wx.NewIdRef()
        self.b1 = wx.Button(self,pos=(100,0))
        self.b2 = wx.Button(self,pos=(100,30))
        self.b3 = wx.Button(self,pos=(100,60))
        self.b4 = wx.Button(self,pos=(100,100))
        self.Show()
        self.RegisterHotKey(self.hotkey, wx.MOD_ALT, wx.WXK_DOWN)

        self.Bind(wx.EVT_HOTKEY, self.hot_key,id=self.hotkey)

    def hot_key(self,e):
        lis=self.GetChildren()      
        if self.b1:
            self.b1.Destroy()

        print(self.__dict__['b1'])
        print(len(lis))               

if __name__ == "__main__":
    app = wx.App(False)
    frame = MyFrame()
    app.MainLoop()

you don’t have to keep a reference at all in python: it’s all in wx :joy:

import wx
class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title='TextCtrl Demo',size=(500,300))
        self.Centre()
        self.hotkey = wx.NewIdRef()
        wx.Button(self,pos=(100,0), name='b1')
        self.b2 = wx.Button(self,pos=(100,30))
        self.b3 = wx.Button(self,pos=(100,60))
        self.b4 = wx.Button(self,pos=(100,100))
        self.Show()
        self.RegisterHotKey(self.hotkey, wx.MOD_ALT, wx.WXK_DOWN)

        self.Bind(wx.EVT_HOTKEY, self.hot_key,id=self.hotkey)

    def hot_key(self,_):
        lis=self.GetChildren()
        if b1 := wx.FindWindowByName('b1', parent=self):
            b1.Destroy()

        print(self.__dict__['b1'])
        print(len(lis))
app = wx.App(False)
MyFrame()
app.MainLoop()

You are nice!!! :+1:

There’s a little more to this I’m afraid.
You should be aware that a Python (widget) object, in wxPython, is a proxy to a wxWidget (c++) object. So, even if you Destroy() the c++ side of the widget, the Python object will still be there, altough no more usable.

>>> import wx
>>> app = wx.App()
>>> widget = wx.Dialog(None)
>>> widget.Destroy()  # even if I kill the c++ widget...
True
>>> widget  # ...its python counterpart is still alive
<wx._core Dialog object at ...>

Of course you could del widget to destroy the python side too… but this is rarely needed: usually, if you don’t need to keep around the python objects, all you have to do is to let them out of scope and have the garbage collector do the job for you.