[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