Why does a frame persist after Destroy?

Hi all,

I’m wondering why a frame still persists after Destroy is called on OS X.

Sample:

import wx
class MyFrame(wx.Frame):
def init(self):
wx.Frame.init(self, None, -1, “A Frame”)
btn = wx.Button(self, -1, “Destroy”)
btn.Bind(wx.EVT_BUTTON, lambda evt: self.Destroy())
self.SetBackgroundColour(wx.WHITE)
self.SetSize((300, 300))
self.CenterOnScreen()
def Destroy(self):
print "Before: ", list(wx.GetTopLevelWindows())
wx.Frame.Destroy(self)
print "After: ", list(wx.GetTopLevelWindows())
app = wx.App()
frame1 = MyFrame()
frame1.Show()
app.MainLoop()

In the code above, the frame is still in wx.GetTopLevelWindows as an active window after Destroy is called. Why? Doesn’t this constitute a leak? How do I eject it from the top level windows (or force process the Destroy call)?

Rishi,

Since you are listing the top level windows from within the frames own
destroy method the code hasn't finished so of course the frame must
still exist at that point or there would be an error trying to execute
no longer present code.

In addition, Destroy and delete mark items as READY for garbage
collection, items can still be present until the garbage collector runs.

···

On 13/09/2016 01:31, Rishi Sharma wrote:

Hi all,

I'm wondering why a frame still persists after Destroy is called on OS X.

Sample:

    import wx
    class MyFrame(wx.Frame):
      def __init__(self):
        wx.Frame.__init__(self, None, -1,"A Frame")
        btn= wx.Button(self, -1, "Destroy")
        btn.Bind(wx.EVT_BUTTON, lambda evt: self.Destroy())
        self.SetBackgroundColour(wx.WHITE)
        self.SetSize((300, 300))
        self.CenterOnScreen()
      def Destroy(self):
        print "Before: ", list(wx.GetTopLevelWindows())
        wx.Frame.Destroy(self)
        print "After: ", list(wx.GetTopLevelWindows())
    app = wx.App()
    frame1 = MyFrame()
    frame1.Show()
    app.MainLoop()

In the code above, the frame is still in wx.GetTopLevelWindows as an
active window after Destroy is called. Why? Doesn't this constitute a
leak? How do I eject it from the top level windows (or force process
the Destroy call)?

--
Steve (Gadget) Barnes
Any opinions in this message are my personal opinions and do not reflect
those of my employer.

I think it may be more complex than that.

IIUC, .Destroy() invokes a C++ method that destroys the underlying C++
object, but leaves the Python wrapper alone.

Which is why you rarely want to call it.

But Think Steve is right -- we does some memory mane gent tricks under
the hood, so the object may persist longer than you'd expect.

The question is--what problem are you trying to solve?

Or are simply trying to understand what's going on under the hood?

Because U doubt that destroying a Frame from within one of its own
methods is a robust approach to real problem.

-CHB

···

Sent from my iPhone

On Sep 12, 2016, at 9:31 PM, Steve Barnes <gadgetsteve@live.co.uk> wrote:

On 13/09/2016 01:31, Rishi Sharma wrote:
Hi all,

I'm wondering why a frame still persists after Destroy is called on OS X.

Sample:

   import wx
   class MyFrame(wx.Frame):
     def __init__(self):
       wx.Frame.__init__(self, None, -1,"A Frame")
       btn= wx.Button(self, -1, "Destroy")
       btn.Bind(wx.EVT_BUTTON, lambda evt: self.Destroy())
       self.SetBackgroundColour(wx.WHITE)
       self.SetSize((300, 300))
       self.CenterOnScreen()
     def Destroy(self):
       print "Before: ", list(wx.GetTopLevelWindows())
       wx.Frame.Destroy(self)
       print "After: ", list(wx.GetTopLevelWindows())
   app = wx.App()
   frame1 = MyFrame()
   frame1.Show()
   app.MainLoop()

In the code above, the frame is still in wx.GetTopLevelWindows as an
active window after Destroy is called. Why? Doesn't this constitute a
leak? How do I eject it from the top level windows (or force process
the Destroy call)?

Rishi,

Since you are listing the top level windows from within the frames own
destroy method the code hasn't finished so of course the frame must
still exist at that point or there would be an error trying to execute
no longer present code.

In addition, Destroy and delete mark items as READY for garbage
collection, items can still be present until the garbage collector runs.

--
Steve (Gadget) Barnes
Any opinions in this message are my personal opinions and do not reflect
those of my employer.

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wxpython-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Oh my example was bad then. I should have had the check outside of the frame. Thanks for pointing that out.

I was able to solve it by explicitly calling wx.Yield after the Destroy method.

···

On Tue, Sep 13, 2016 at 1:02 PM, Chris Barker - NOAA Federal chris.barker@noaa.gov wrote:

I think it may be more complex than that.

IIUC, .Destroy() invokes a C++ method that destroys the underlying C++

object, but leaves the Python wrapper alone.

Which is why you rarely want to call it.

But Think Steve is right – we does some memory mane gent tricks under

the hood, so the object may persist longer than you’d expect.

The question is–what problem are you trying to solve?

Or are simply trying to understand what’s going on under the hood?

Because U doubt that destroying a Frame from within one of its own

methods is a robust approach to real problem.

-CHB

Sent from my iPhone

On Sep 12, 2016, at 9:31 PM, Steve Barnes gadgetsteve@live.co.uk wrote:

On 13/09/2016 01:31, Rishi Sharma wrote:

Hi all,

I’m wondering why a frame still persists after Destroy is called on OS X.

Sample:

import wx

class MyFrame(wx.Frame):

 def __init__(self):
   wx.Frame.__init__(self, None, -1,"A Frame")
   btn= wx.Button(self, -1, "Destroy")
   btn.Bind(wx.EVT_BUTTON, lambda evt: self.Destroy())
   self.SetBackgroundColour(wx.WHITE)
   self.SetSize((300, 300))
   self.CenterOnScreen()
 def Destroy(self):
   print "Before: ", list(wx.GetTopLevelWindows())
   wx.Frame.Destroy(self)
   print "After: ", list(wx.GetTopLevelWindows())

app = wx.App()

frame1 = MyFrame()

frame1.Show()

app.MainLoop()

In the code above, the frame is still in wx.GetTopLevelWindows as an

active window after Destroy is called. Why? Doesn’t this constitute a

leak? How do I eject it from the top level windows (or force process

the Destroy call)?

Rishi,

Since you are listing the top level windows from within the frames own

destroy method the code hasn’t finished so of course the frame must

still exist at that point or there would be an error trying to execute

no longer present code.

In addition, Destroy and delete mark items as READY for garbage

collection, items can still be present until the garbage collector runs.

Steve (Gadget) Barnes

Any opinions in this message are my personal opinions and do not reflect

those of my employer.

You received this message because you are subscribed to the Google Groups “wxPython-users” group.

To unsubscribe from this group and stop receiving emails from it, send an email to wxpython-users+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

You received this message because you are subscribed to the Google Groups “wxPython-users” group.

To unsubscribe from this group and stop receiving emails from it, send an email to wxpython-users+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.