I'm working on a small gui in wxPython
.
One part of the program connects to a webpage to get some updates. It prints this info to a status TextCtrl
.
Now, I could do this trivially in one thread, but the program will of course become unresponsive while the request to the webpage is being made. So, to get around this, I've created two additional threads that start at the beginning of the program and simply block until they get some work to do. One loads the page, and one writes to the status box.
I'm using a kind of producer/consumer style where everything is passed around with Queue
s.
First class:
class Loader(threading.Thread):
def __init__(self, in_queue, msg_queue):
threading.Thread.__init__(self)
self.in_queue = in_queue
self.msg_queue = msg_queue
def run(self):
url = self.in_queue.get()
page = Page(url)
self.msg_queue.put('requested page %s' % page.get_title())
self.in_queue.task_done()
So, it waits for a url, then opens the url (Page
is another custom class which just stores a couple of convenience methods for processing the returned html). Then it pushes whatever it wants to print to the TextCtrl
to a msg_queue
.
Second class accepts that msg_queue
.
class StatusWriter(threading.Thread):
def __init__(self, msg_queue, post_func):
threading.Thread.__init__(self)
self.msg_queue = msg_queue
self.post_message = post_func
def run(self):
while True:
messgae = self.msg_queue.get()
if messgae == 'quit':
self.msg_queue.task_done()
break
self.post_message(messgae)
self.msg_queue.task_done()
So here is where my question is. Right now, I'm not sure how to control my various wx widgets from a separate class. I've gotten around this by taking advantage of the fact that you can pass around functions, but I'm not sure if this is the correct way to go about this. It seems like it's a strange to give one tiny function from one class to another class.
The function in question is:
def post_status_update(self, msg=None):
self.status_box.AppendText(msg)
And everything gets set up as:
self.in_queue = Queue.Queue()
self.msg_queue = Queue.Queue()
self.loader = Loader(self.in_queue, self.msg_queue)
self.status_writer = StatusWriter(
self.in_queue,
self.msg_queue,
self.post_status_update()
)
So, my question is basically, is this an "incorrect" way to go about this? It feels like it's tightly coupling this class to a very specific part of the gui's code.