Design Question: GUI+Threads.

Brian Kelley bkelley at wi.mit.edu
Fri Oct 24 12:06:55 EDT 2003


Frithiof Andreas Jensen wrote:
> Thaks for the reply,
> 
> "Brian Kelley" <bkelley at wi.mit.edu> wrote in message
> news:3f97ee4a$0$573$b45e6eb0 at senator-bedfellow.mit.edu...
> 
>>Syver Enstad wrote:
>>
> 
> 
>>You might make your life easier by having the controller and the view be
>>on the main thread and dispatch a new model to the work thread.
> 
> 
> Hmm. I think that makes sense, since it is the GUI that "demands"
> attention - I was doing sort-of  the other way round by having a thread
> dispatching messages to models AND the GUI thread....
> 
> <snip> 
> I was planning to use of a Dispatcher/Mailbox System:
> 
> The worker thread(S) blocks on an input queue until a message is in that
> queue - then the worker thread process the message and places a result in an
> output queue. The results in the output queue(s) of each worker are read by
> the main thread and placed in the input queues of other workers or in the
> GUI.....most of the time a worker will sleep, waiting for work.

This seems very doable.  You have at least two options: 1) use a wxTimer 
to periodically tell the controller to check the worker's output queues 
or 2) have the worker send a new wxEvent to the view with the result 
data.  This could be as simple as:

wxEVT_WORKER_RESULT = wxNewEventType()

def EVT_WORKER_RESULT(win, func):
     win.Connect(-1, -1, wxEVT_WORKER_RESULT, func)

class WorkerResultEvent(wxPyEvent):
     def __init__(self, result):
         wxPyEvent.__init__(self)
         self.SetEventType(wxEVT_WORKER_RESULT)
         self.data = data

# event wrapper so that the worker thread can send
# results
class EventWrapper:
     def __init__(self, window):
         self.window = window
     def setResult(self, data):
         wxPostEvent(self.win, WorkerResultEvent(data))

class WorkerThread(thread):
    def __init__(self, eventSender):
        ...
    def Run(self): ...
        ...
        self.eventSender(result)
        self.blockForNextJob()

class View:
    def __init__(self, controller,...):
        EVT_WORKER_RESULT(self, self.OnResult)
    def OnResult(self, evt):
        self.controller.OnResult(evt.result)

A good example of this is in the wxPython thread example.  Their view is 
their controller though.





More information about the Python-list mailing list