那么我应该在程序的开头运行什么才能使它成为线程安全的(或者我在某些地方读过的线程感知):
from gi.repository import Gtk, Gdk, GLib, GObject
import threading
GLib.threads_init() # ?
GObject.threads_init() # YES!
Gdk.threads_init() # ?
my_app()
def my_threaded_func():
Glib.idle_add(lambda: some_gui_action())
Glib.timeout_add(300, lambda: some_gui_action())
t = threading.Thread(target=my_thread_func)
t.daemon = True
t.start()
Gtk.main()
然后,我应该在我的线程中做什么?某种锁?使用Python的线程库是安全的还是我应该在GLib,GObject或Gdk中使用某些东西?我知道那里有很多问题/答案/例子,但它们都相互矛盾,不是Gtk + 3,不是Python,或者只是不完整,甚至我认为是Python GI的官方文档({ {3}})甚至没有提到GObject.threads_init()和Gdk.threads_init()的存在。
答案 0 :(得分:12)
https://wiki.gnome.org/Projects/PyGObject/Threading
..但是,Gdk.threads_init() is deprecated,我建议:
为什么:
关于其他图书馆:
tl; dr:只有GObject.threads_init(),在线程中使用 GLib.idle_add
答案 1 :(得分:0)
如果有人要在多线程代码中使用GTK,那么必须阅读文档。 https://wiki.gnome.org/Attic/GdkLock
这个文档真的帮助我理解了如何在一个进程中从C运行GTK以及从python运行GTK(通过PyGTK只是在python中导入gtk)。虽然可以通过XInitThreads()
在Linux中避免使用GDK锁,但它不是Windows的解决方案。像g_idle_add()
或g_timeout_add()
这样的函数是防止GUI压缩的通用解决方案。但是gdk_threads_enter()和gdk_thread_leave()还没有完全没用。该文档阐明了如果有人想要从不同的线程或自定义事件处理程序或g_idle_add()
回调更新GUI,如何安全地使用这些锁。