Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用PyGtk时未从另一个线程更新GUI_Python_Multithreading_Pygtk - Fatal编程技术网

Python 使用PyGtk时未从另一个线程更新GUI

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+中排队 如果需要运行多

我正在使用PyGTK构建GUI应用程序。我想从另一个线程更新textview小部件,但该小部件不会在每次尝试更新时都得到更新。我应该怎么做才能获得可靠的GUI更新?

GTK+不是线程安全的,因此您不应该简单地从其他线程调用GUI更新方法。(或gobject.idle_加载项较早的PyGTK版本)可用于此目的

而不是写:

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条目中看到: