If you've ventured just a little bit into GTK and threading, you have probably noticed how things can explode if you manipulate GTK objects directly from a thread. GTK is not threadsafe.
However, this tip might help you get stuff done properly:
1) Do your actual work in a thread and give the thread callbacks for whenever it wants to update the UI. Keep those callbacks in your UT classes.
2) Make sure that those callbacks (since they are called from separate threads) add their work to the GTK work schedular with
Here is the decorator, you should use! Remember that since idle_add does not work with kwargs, your decorated method has to use positional arguments.
import gobject def idle_add_decorator(func): def callback(*args): gobject.idle_add(func, *args) return callback
Here is an example of using it:
class MyWindow(gtk.Window): def on_some_event(self, *args): @idle_add_decorator def create_dialog(): dialog = gtk.MessageDialog(parent=None, type=gtk.MESSAGE_QUESTION, buttons = gtk.BUTTONS_YES_NO, message_format="Are you sure?") dialog.connect("response", hande_event) dialog.connect("close", hande_event, gtk.RESPONSE_NO) dialog.show() @idle_add_decorator def hande_event(dialog, response_id, *args): if dialog: dialog.destroy() if response_id == gtk.RESPONSE_NO: return try: def my_thread(): create_dialog() while True: print "Yo!" time.sleep(10) t = threading.Thread(target=my_thread) t.start()
So what's the example about? Well, we have
my_thread - that's just a function that loops forever inside a thread. The first thing it does, however, is to create a gtk Dialog, and to do that, it should add itself to the job queue to avoid performing unsafe thread stuff. So that's where you add the decorator! And why does
@idle_add_decorator also occur above
hande_event? Well, it doesn't have to, because an event callback is already performed inside the GTK main loop - but basically, it will delay itself a little bit by moving down the queue at first, but on the other hand you might want to get some sort of habbit. Either always playing it safe by using the decorator - or - prefixing your event handlers with
on_xxx so you know when something can only be called from the main thread.