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

发布于 2024-08-18 01:55:03 字数 89 浏览 8 评论 0原文

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

街角卖回忆 2024-08-25 01:55:03

GTK+ 不是线程安全的,因此您不应该简单地从其他线程调用 GUI 更新方法。 glib.idle_add (或 gobject.idle_add在较旧的 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;否则会再次排队。

编辑:正如 Daniel 指出的,您需要首先在程序中的任何位置调用 gtk.gdk.threads_init()

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.

风筝在阴天搁浅。 2024-08-25 01:55:03

正如前面的答案所述,GTK 不是“线程安全”的,但它是“线程感知的” - 请参阅有关线程的此页面: https://developer.gnome.org/gdk2/stable/gdk2-Threads.html

为了从另一个线程修改 GTK 小部件,您必须使用GTK的锁定。导入 gtk 模块后立即调用 gtk.threads_init() ,然后您可以像这样更新:

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

请注意,上述内容在 Windows 上不起作用(请参阅上面的链接)。在 Windows 上,您必须按照上面的说明使用 gobject.idle_add(),不过不要忘记在代码中导入 gobject 后直接放置 gobject.threads_init()! idle_add() 函数将在主线程(运行 gtk.main() 的线程)中执行更新本身。

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()).

零度℉ 2024-08-25 01:55:03

使用 gobject.idle_add 方法可以实现相同的效果,其语法与上面相同,您必须导入模块 gobject

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

我的奇迹 2024-08-25 01:55:03

Johannes 所说的是正确的,但是由于 GTK 是 glib 和 gobject 事物的包装器,因此您实际上需要使用 gtk.idle_add()。不需要不必要的进口。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文