On 02/20/2011 03:08 PM, Stephen Langer wrote:
This is what we do:
class IdleBlockCallback:
def __init__(self, func, args=(), kwargs={}):
self.func = func
self.args = args
self.kwargs = kwargs
self.event = threading.Event()
self.result = None
def __call__(self):
gtk.gdk.threads_enter()
try:
self.result = self.func(*self.args, **self.kwargs)
finally:
gtk.gdk.flush()
gtk.gdk.threads_leave()
self.event.set()
return False # don't repeat
def runBlock(func, args=(), kwargs={}):
callbackobj = OOFIdleBlockCallback(func, args, kwargs)
callbackobj.event.clear()
gobject.idle_add(callbackobj, priority=gobject.PRIORITY_LOW)
callbackobj.event.wait()
return callbackobj.result
Thank you, thank you, thank you - this is exactly what I was looking
for. For some reason, I didn't think to look in Python's threading
module. Two questions:
1) Since all GTK stuff is happening in the mainloop thread, I'm only
calling gobject.threads_init(), not gtk.gdk.threads_init() (as suggested
here: http://library.gnome.org/devel/gtk-faq/stable/x499.html) Am I
correct in understanding that I don't need to call
gtk.gdk.threads_enter() and _leave() in the callback? (I've taken them
out, and nothing seemed to break.) What about the flush()?
2) I'd like to use this code in a project to be released under the BSD
license. Is that okay with you?
Call runBlock on the worker thread. Be sure that you're really on the worker
thread, because if you call it on the main thread it will hang.
If I understand things correctly (unlikely), gobject.main_depth() will
be greater than zero in the main loop thread and zero in the worker
threads. (At least if I only start the main loop in one thread.) So
I've written this function to ensure code is called in the main loop.
Limited testing suggests it's working.
def run_in_main_loop(func, *args, **kwargs):
if gobject.main_depth():
# In the main loop already
return func(*args, **kwargs)
callbackobj = IdleBlockCallback(func, args, kwargs)
callbackobj.event.clear()
gobject.idle_add(callbackobj, priority=gobject.PRIORITY_LOW)
callbackobj.event.wait()
return callbackobj.result
Thanks again,
Robert
_______________________________________________
pygtk mailing list [email protected]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://faq.pygtk.org/