How to force deletion of widgets

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

How to force deletion of widgets

efahl

Our application has a Logger class that tees output to many destinations (log files, gui window, error dialogs and so on).  When run interactively, it works fine, but when run in test mode where the app.MainLoop is never entered, it crashes because the widgets are not destroyed completely at exit time.  I've also tried adding an idle event handler to my main window, which senses we're in test mode and does an app.Exit() immediately upon entering the MainLoop code, but that behaves exactly as if we had never entered MainLoop, too.

 

So, how can I force destruction of the wxPython objects truly and completely, so that they become DeadObjects before my atexit handlers are fired off?

 

> ./krash.py  # Run interactively, window pops up and click [X].  Works fine.

mw = wxPython wrapper for DELETED Frame object! (The C++ object no longer exists.)

It's dead, Jim.

 

> ./krash.py --batch # Run in test mode.

mw = <wx._windows.Frame; proxy of <Swig Object of type 'wxFrame *' at 0x2425f30> >

Go ahead and use it.  # But if you do, you'll cause a seg fault.

 

Here's my test code:

 

#!/usr/bin/env python

 

import sys, wx, atexit

 

app = wx.App(redirect=False)

mw  = wx.Frame(None)

mw.Show()

 

def cleanup():

   print "mw =", mw

   if mw:

      print "Go ahead and use it."

   else:

      print "It's dead, Jim."

atexit.register(cleanup)

 

if "--batch" not in sys.argv:

   app.MainLoop()

else:

   mw.Destroy()

   app.Yield() # or app.ProcessPendingEvents() or any number of other things...

 

app.Destroy()

--
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: How to force deletion of widgets

efahl
Oops, forgot version info: Win 7 64, wxPython 2.8.12.0

On Friday, April 18, 2014 10:36:02 AM UTC-7, efahl wrote:

Our application has a Logger class that tees output to many destinations (log files, gui window, error dialogs and so on).  When run interactively, it works fine, but when run in test mode where the app.MainLoop is never entered, it crashes because the widgets are not destroyed completely at exit time.  I've also tried adding an idle event handler to my main window, which senses we're in test mode and does an app.Exit() immediately upon entering the MainLoop code, but that behaves exactly as if we had never entered MainLoop, too.

 

So, how can I force destruction of the wxPython objects truly and completely, so that they become DeadObjects before my atexit handlers are fired off?

 

> ./krash.py  # Run interactively, window pops up and click [X].  Works fine.

mw = wxPython wrapper for DELETED Frame object! (The C++ object no longer exists.)

It's dead, Jim.

 

> ./krash.py --batch # Run in test mode.

mw = <wx._windows.Frame; proxy of <Swig Object of type 'wxFrame *' at 0x2425f30> >

Go ahead and use it.  # But if you do, you'll cause a seg fault.

 

Here's my test code:

 

#!/usr/bin/env python

 

import sys, wx, atexit

 

app = wx.App(redirect=False)

mw  = wx.Frame(None)

mw.Show()

 

def cleanup():

   print "mw =", mw

   if mw:

      print "Go ahead and use it."

   else:

      print "It's dead, Jim."

atexit.register(cleanup)

 

if "--batch" not in sys.argv:

   app.MainLoop()

else:

   mw.Destroy()

   app.Yield() # or app.ProcessPendingEvents() or any number of other things...

 

app.Destroy()

--
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: How to force deletion of widgets

Dev Player
This worked for me.

import sys, wx, atexit
 
app = wx.App(redirect=False)
mw  = wx.Frame(None)
mw.Show()
 
def cleanup():
   print "mw =", mw
   if mw:
      if mw.IsBeingDeleted():
    print "It is being deleted." # not revelent
      else:
         print "Go ahead and use it."
   else:
      print "It's dead, Jim."
atexit.register(cleanup)
 
if "--batch" not in sys.argv:
   app.MainLoop()
else:
   mw.Destroy()
   app.MainLoop()
 
app.Destroy()



On Fri, Apr 18, 2014 at 3:20 PM, efahl <[hidden email]> wrote:
Oops, forgot version info: Win 7 64, wxPython 2.8.12.0


On Friday, April 18, 2014 10:36:02 AM UTC-7, efahl wrote:

Our application has a Logger class that tees output to many destinations (log files, gui window, error dialogs and so on).  When run interactively, it works fine, but when run in test mode where the app.MainLoop is never entered, it crashes because the widgets are not destroyed completely at exit time.  I've also tried adding an idle event handler to my main window, which senses we're in test mode and does an app.Exit() immediately upon entering the MainLoop code, but that behaves exactly as if we had never entered MainLoop, too.

 

So, how can I force destruction of the wxPython objects truly and completely, so that they become DeadObjects before my atexit handlers are fired off?

 

> ./krash.py  # Run interactively, window pops up and click [X].  Works fine.

mw = wxPython wrapper for DELETED Frame object! (The C++ object no longer exists.)

It's dead, Jim.

 

> ./krash.py --batch # Run in test mode.

mw = <wx._windows.Frame; proxy of <Swig Object of type 'wxFrame *' at 0x2425f30> >

Go ahead and use it.  # But if you do, you'll cause a seg fault.

 

Here's my test code:

 

#!/usr/bin/env python

 

import sys, wx, atexit

 

app = wx.App(redirect=False)

mw  = wx.Frame(None)

mw.Show()

 

def cleanup():

   print "mw =", mw

   if mw:

      print "Go ahead and use it."

   else:

      print "It's dead, Jim."

atexit.register(cleanup)

 

if "--batch" not in sys.argv:

   app.MainLoop()

else:

   mw.Destroy()

   app.Yield() # or app.ProcessPendingEvents() or any number of other things...

 

app.Destroy()

--
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 [hidden email].
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: How to force deletion of widgets

Robin Dunn
In reply to this post by efahl
Eric Fahlgren wrote:

> Our application has a Logger class that tees output to many destinations
> (log files, gui window, error dialogs and so on). When run
> interactively, it works fine, but when run in test mode where the
> app.MainLoop is never entered, it crashes because the widgets are not
> destroyed completely at exit time. I've also tried adding an idle event
> handler to my main window, which senses we're in test mode and does an
> app.Exit() immediately upon entering the MainLoop code, but that behaves
> exactly as if we had never entered MainLoop, too.
>
> So, how can I force destruction of the wxPython objects truly and
> completely, so that they become DeadObjects before my atexit handlers
> are fired off?

You can probably go ahead and just run MainLoop before you exit.  If all
top-level windows have already been closed then MainLoop will destroy
them and then exit.  (In more detail, it will process pending events,
run any bound IDLE handlers, destroy anything in the pending delete
list, etc. And then when it gets to the top of the loop again and sees
that there are no longer any top-level windows it will terminate the loop.)

--
Robin Dunn
Software Craftsman
http://wxPython.org

--
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.