Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

wxpython -- threads and window events

I have a wxPython application (http://www.OpenSTV.org) that counts ballots using methods that have multiple rounds. I'd like to do two things:

(1) For a large number of ballots, this can be a bit slow, so I'd like to show the user a progress dialog so he doesn't think the application is frozen.

(2) I'd like to allow the user to break ties manually, and this requires the counting code to show a dialog window.

To achieve (1), I create a thread to run the counting code, and this allows me to present a nice progress dialog to the user.

The problem with this, however, is that the counting code is not the main thread, and only the main thread in wxPython can process window events.

I suppose I could create a thread to run the progress dialog instead, but this seems awkward. Is there a better way of accomplishing both (1) and (2)?

like image 436
gaefan Avatar asked Mar 01 '23 06:03

gaefan


1 Answers

Use Queue to communicate and synchronize among threads, with each thread "owning" and exclusively interacting with a resource that's not handy to share.

In GUI toolkits where only the main thread can really handle the GUI, the main thread should play along -- set up and start the threads doing the actual work, then do nothing but GUI work, using Queues to communicate to and from the other threads.

For (1), when your counting thread has an update, it should put it to the Queue where the main thread is waiting; when your main thread gets a suitable message on that Queue, it updates the progress dialog.

For (2), the counting thread sends the "have the user break a tie" request, main thread gets it and responds appropriately, and sends back the resolution on a separate Queue.

So in general, there are two kinds of communications: one that don't require a response, and others that do. For the former kind, just put the notification on the appropriate queue and simply proceed -- it will be acted on in due course. For the latter kind, my favorite idiom is to put on the appropriate queue a pair (request, response_queue). If otherwise identical requests differ in that some need a response and others don't, queueing (request, None) when no response is needed (and (request, q) where q's a Queue when a response IS needed) is a nice, easy, and general idiom, too.

like image 162
Alex Martelli Avatar answered Mar 07 '23 23:03

Alex Martelli