wxPython and threads again

David E. Konerding DSD staff dek at scooby.lbl.gov
Thu Aug 11 12:05:06 EDT 2005


On 2005-08-10, Peter Hansen <peter at engcorp.com> wrote:
> David E. Konerding DSD staff wrote:
>> Further, calling wx from a thread other than the one running the event 
> > loop is deep voodoo and should typically be avoided.
>
> "Typically"?  Let's just say "always" and maybe use the phrase "certain 
> to corrupt wx and crash the app" instead of "deep voodoo". :-)  At least 
> that way the OP won't waste time experimenting...

Not really certain:
http://wxwidgets.org/manuals/2.6.1/wx_threadfunctions.html#threadfunctions

This strongly suggests you can arbitrarily grab the wx GUI lock and call GUI
functions from any thread.  It's still voodoo.  But we're adults here, and practicing
voodoo isn't proscribed.

>
>> You need another way to pass completion information between the downloader
>> thread and the main thread; the simplest way is to define a custom wx
>> Event, and wxPostEvent from the downloader thread when it completes (
>> and when the gauge should be updated).  wxPostEvent is safe to call from non-eventloop threads.
>> The main thread's wx event loop just spins, properly updating all other
>> parts of the GUI, and receiving events from the downloader thread.
>
> Even simpler for some purposes is wx.CallAfter(), which provides the 
> asynchronous performance of wxPostEvent with the "beautifully general" 
> approach of passing callables through a Queue which Bryan Olson 
> described in his post.  (That is, you don't need to do polling with a 
> non-blocking get() on the Queue this way.)

Very good point.  I wasn't aware CallAfter had those semantics; I always used it from
the main thread.  But won't wx.CallAfter cause a bit of a delay since it will wait until
all pending events are processed and only handle the function afterwards, thus inducing
an extra event loop cycle/redraw?

Dave



More information about the Python-list mailing list