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 . 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…
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 . 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…
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 . 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.
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.)