[wxPython-users] calling wx.CallAfter after wx.Frame.Destroy
Aaron Brady
castironpi at comcast.net
Mon Jan 21 18:20:35 PST 2008
> -----Original Message-----
> From: Robin Dunn [mailto:robin at alldunn.com]
> Sent: Monday, January 21, 2008 7:37 PM
> > Will MainLoop exit if other events are added to the event queue after or
> > during delete, or will it address those first? IOW in other words, when
> > does it return?
>
> IIRC, it's a little different depending on how the platform specific
> event loops are handled, but in general when a TLW is finally destroyed
> wx checks if is was the last one in the top level window list, if so
> then it sets a flag that is checked in the next iteration of the main
> loop.
>
> >
> > If one calls CallAfter while or after the pending delete queue is being
> > processed, are further references are invalid?
>
>
> The order of execution is essentially something like this pseudo-code:
>
> while not exitFlag:
> while native events waiting:
> get next native event
> process native event
>
> process posted events
> send idle event
> delete destroyed TLWs
>
>
> The wx.CallAfter's are implemented by posting events, so they are called
> before the pending delete queue is checked. So yes it is possible that
> a TLW or widget used by a CallAfter function is not valid at the time
> the function is called, however if that was the last TLW and the main
> loop is exiting then it is probably not likely.
Fine. Where is exitFlag set?
destroytype.process:
exitFlag= True?
process native event:
eventtype.process
> If in doubt it is easy
> to check. When a C++ widget object is deleted and it knows what it's
> Python proxy object is, andif there is more than one reference to that
> proxy then wxPython will replace the __class__ of that proxy object with
> one that raises an exception if you try to evaluate any of it's
> attributes (the PyDeadObjectError exception) and it also has a
> __nonzero__ method that returns False. That means that you can use a
> simple if test to see if the widget is still alive, like this:
>
> def MyCallAfterFunction(frame):
> if frame:
> frame.DoSomething()
It's only if it might be running in a second thread that awry might it go;
if between 'if frame' and 'frame.What', MainLoop destroys, or worse, begins
to destroy frame.
(*) def MyCallAfterFunction(frame):
if frame:
<thread turnover to MainLoop destroys frame>
frame.DoSomething()
* Invalid
More information about the wxpython-users
mailing list