On Wed, 2010-07-07 at 09:26 +0800, Jason Heeris wrote: > Tim Evans wrote: > > GTK+ 2.14.4 > > PyGObject 2.14.2 > > PyGTK 2.12.1 > > Mine is > > GTK+ 2.20 > PyGObject 2.21.2 > PyGTK 2.17.1 > > A few things about your changes confused me - > > 1. You call glib.idle_add, but never called glib.threads_init - won't > this break on Linux? > 2. You use BOTH gtk.gdk.lock and glib.idle_add - but surely one of > these is superfluous, since glib.idle_add executes the function in the > main loop, where the lock is already acquired? > > Anyway, I came up with a different, simpler way, but I don't know > enough to say if it will never fail. I can't push to github from here, > but basically it's the same as my first example[1] but with this main > block for controller.py: > > ---- > if __name__ == "__main__": > > import glib > import gtk.gdk > gtk.gdk.threads_init() > glib.threads_init() > > view = MyView() > model = MyModel() > controller = MyController(model, view) > > with gtk.gdk.lock: > LaunchUI(view) > ---- > > Works on both win32 and linux, using glib.idle_add throughout. I was a > bit worried that trying to acquire the gtk.gdk.lock from the main > thread would cause problems under linux as per [2], but it works fine.
This is more or less my approach to. On both windows and linux I successfully use this idiom as follows glib.threads_init() gtk.gdk.threads_init() class App: .. do ui stuff, start worker thread/s .. def main() if is_windows: gtk.gdk.threads_enter() gtk.main() if is_windows: gtk.gdk.threads_leave() def frobnicate(self, foo): return False class ThreadWorker(threading.Thread) def run() while self.running: if something_interesting(): gobject.idle_add(self.app.frobnicate, foo, priority=gobject.PRIORITY_HIGHEST) or I use the idiom described here; http://www.johnstowers.co.nz/blog/index.php/2007/03/12/threading-and-pygtk/ Which is basically the same, except ThreadWorker is also a GObject and signal emission is done in idle_add, hence all connected signal callbacs get called in the gtk.main thread John > > Lessons learnt: > > 1. Call gtk.gdk.threads_init() BEFORE glib.threads_init() (otherwise > glib.idle_add won't work) > 2. Call them both before you do anything else > 3. Start the main loop in the gtk.gdk.lock context manager or > surrounded by gtk.gdk.threads_enter/leave() > > Thanks for everyone's patience - I rarely have to develop under win32, > so I'm not really aware of these gotchas. > > - Jason > > [1] http://github.com/detly/gtk-async-test > [2] http://faq.pygtk.org/index.py?req=show&file=faq20.015.htp > _______________________________________________ > pygtk mailing list pygtk@daa.com.au > http://www.daa.com.au/mailman/listinfo/pygtk > Read the PyGTK FAQ: http://faq.pygtk.org/ _______________________________________________ pygtk mailing list pygtk@daa.com.au http://www.daa.com.au/mailman/listinfo/pygtk Read the PyGTK FAQ: http://faq.pygtk.org/