Here's a simple script that demonstrates creating a standard Python
thread, passing it arguments, blocking on it, and getting a return
value via a queue:
import Queue
import threading
def crunch(a, b, c, resultQueue):
resultQueue.put((a * b) + c)
resultQueue = Queue.Queue()
thread = threading.Thread(target = crunch, args = [3, 5, 7, resultQueue])
thread.start()
thread.join()
print resultQueue.get()
Since you don't want to have your main thread block while the
data-cruncher runs, instead of having the "thread.join()" call (which
will block on the thread completion) and the queue, you can do
something like this instead at the end of crunch():
wx.CallAfter(processResult, (a * b) + c)
where processResult is another function, accepting one argument in this case.
Hope that helps.
-Chris
A common pattern for doing this is a command queue. Basically you have
a queue object that the gui thread will add command objects to. Those
commands can be anything that is able to carry the information that you
want to be able to pass to the worker thread. Typically they would be
instances of some Command class that is specific to your application's
needs but really anything will work. When you create the worker thread
you give it a reference to that queue and it starts a loop that reads
the next command object from the queue, performs the command (whatever
it may be) and then does something with the results. (You could even do
something like have one of the attributes in the command object be a
function that should be called when the command is completed.) Since
Python's queue.Queue class is thread safe and will block in get() by
default if there are no items waiting in the queue yet then it is
perfect for implementing this pattern. You can also have more than one
instance of the worker thread processing items in the queue if needed.
Remember that anything that interacts with the GUI needs to be done in
the GUI thread, so you'll need to ensure that the results of the
worker(s) is passed to the GUI thread first before they are displayed in
the GUI. wx.CallAfter has a convenient side-effect that it is
thread-safe and will always call the function you pass it in the UI
thread as soon as any current and pending events are processed.
--
Robin Dunn
Software Craftsman
http://wxPython.org