我正在使用PyGTK构建GUI应用程序。 我想从另一个线程更新textview小部件,但每次尝试更新时该小部件都没有被更新。 我该怎么做才能获得可靠的GUI更新?
我正在使用PyGTK构建GUI应用程序。 我想从另一个线程更新textview小部件,但每次尝试更新时该小部件都没有被更新。 我该怎么做才能获得可靠的GUI更新?
GTK+不是线程安全的,因此您不应该从其他线程直接调用GUI更新方法。glib.idle_add(或在旧版PyGTK中使用的gobject.idle_add)可用于此目的。
不要写成:
label.set_text("foo")
你需要写:
glib.idle_add(label.set_text, "foo")
这会导致函数调用在GTK+中被排队。
如果您需要运行多个语句,通常更容易将它们包装在一个函数中:
def idle():
label1.set_text("foo")
label2.set_text("bar")
glib.idle_add(idle)
确保传递给 idle_add
的函数没有返回 True
,否则它会被再次排队。
编辑:如 Daniel 指出的那样,你需要在程序中的任何地方先调用 gtk.gdk.threads_init()
。
gtk.threads_init()
,然后可以像这样更新:gtk.threads_enter()
# make changes...
gtk.threads_leave()
gobject.idle_add()
方法,但不要忘记在代码中导入gobject后直接添加gobject.threads_init()
!idle_add()函数将在主线程(运行gtk.main()的线程)中执行更新。使用gobject.idle_add方法也可以实现相同的效果,其语法与上述相同,您需要导入gobject模块。
Johannes所说的是正确的,但由于GTK是glib和gobject的包装器,您实际上应该使用gtk.idle_add()。不需要进行不必要的导入。