Python 使用PyGtk时未从另一个线程更新GUI
我正在使用PyGTK构建GUI应用程序。我想从另一个线程更新textview小部件,但该小部件不会在每次尝试更新时都得到更新。我应该怎么做才能获得可靠的GUI更新?GTK+不是线程安全的,因此您不应该简单地从其他线程调用GUI更新方法。(或gobject.idle_加载项较早的PyGTK版本)可用于此目的 而不是写:Python 使用PyGtk时未从另一个线程更新GUI,python,multithreading,pygtk,Python,Multithreading,Pygtk,我正在使用PyGTK构建GUI应用程序。我想从另一个线程更新textview小部件,但该小部件不会在每次尝试更新时都得到更新。我应该怎么做才能获得可靠的GUI更新?GTK+不是线程安全的,因此您不应该简单地从其他线程调用GUI更新方法。(或gobject.idle_加载项较早的PyGTK版本)可用于此目的 而不是写: label.set_text("foo") 你会写: glib.idle_add(label.set_text, "foo") 这将导致函数调用在GTK+中排队 如果需要运行多
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
;否则它将再次排队
Edit:正如Daniel指出的,您需要首先在程序中的任何地方调用
gtk.gdk.threads\u init()
。同样的方法也可以使用gobject.idle\u add方法实现,该方法的语法与上面相同,您必须导入模块gobject,正如前面的回答中所述,gtk不是“线程安全的”,但它是安全的“线程感知”-参见本页关于线程的内容:
为了从另一个线程修改GTK小部件,您必须使用GTK的锁定。导入GTK模块后立即调用GTK.threads_init()
,然后您可以这样更新:
gtk.threads_enter()
# make changes...
gtk.threads_leave()
请注意,上述操作在Windows上不起作用(请参见上面的链接)。在Windows上,您必须按照上面的说明使用
gobject.idle\u add()
,但不要忘记在代码中导入gobject后直接将gobject.threads\u init()
。idle\u add()函数将在主线程中执行更新本身(运行gtk.main()的线程)。Johannes所说的是正确的,但是由于gtk是glib和gobject事物的包装器,您实际上需要使用gtk.idle_add()。不需要不必要的导入。这是一个很好的观点。关于这两种方法的另一篇文章可以在PyGTK FAQ条目中看到: