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/

Reply via email to