8

I am using PyGTK to build a GUI application. I want to update the textview widget from another thread but the widget is not getting updated everytime i try an update. What should i do to get a reliable GUI updating?

appusajeev
  • 2,129
  • 3
  • 22
  • 20

4 Answers4

15

GTK+ is not thread-safe, so you should not simply call GUI update methods from other threads. glib.idle_add (or gobject.idle_add in older PyGTK versions) can be used for this purpose.

Instead of writing:

label.set_text("foo")

you would write:

glib.idle_add(label.set_text, "foo")

which causes the function call to be queued in GTK+.

If you need to run multiple statements, it's often easier to wrap them in a function:

def idle():
    label1.set_text("foo")
    label2.set_text("bar")
glib.idle_add(idle)

Make sure that the function passed to idle_add does not return True; otherwise it will be queued again.

Edit: As Daniel pointed out, you need to call gtk.gdk.threads_init() anywhere in your program first.

Community
  • 1
  • 1
Johannes Sasongko
  • 4,178
  • 23
  • 34
2

As stated in the previous answers, GTK is not "thread safe," but it is "thread-aware" - see this page on Threads: https://developer.gnome.org/gdk2/stable/gdk2-Threads.html

In order to modify GTK widgets from another thread you have to use GTK's locking. Call gtk.threads_init() immediately after importing the gtk module, and then you can update like so:

gtk.threads_enter()
# make changes...
gtk.threads_leave()

Note that the above will not work on Windows (see the link above). On Windows you must use gobject.idle_add() as explained above, though don't forget to put gobject.threads_init() directly after importing gobject in your code! The idle_add() function will execute the update itself in the main thread (the thread running gtk.main()).

SiHa
  • 7,830
  • 13
  • 34
  • 43
Daniel G
  • 67,224
  • 7
  • 42
  • 42
  • Good point. Another good write-up regarding these two approaches can be seen in a PyGTK FAQ entry: http://faq.pygtk.org/index.py?file=faq20.006.htp&req=show – Johannes Sasongko Jan 15 '10 at 08:13
-1

the same may be achieved using gobject.idle_add method whose syntax is same as above,you have to import the module gobject

-1

What Johannes said is correct, however since GTK is a wrapper for the glib and gobject things, you would actually want to use gtk.idle_add(). No need for the unnecessary imports.

excid3
  • 1,658
  • 15
  • 31