5

我对 pygtk 中的线程有疑问。我的应用程序包含一个从 Internet 下载图片然后使用 pygtk 显示的程序。问题是,为了做到这一点并保持 GUI 响应,我需要使用线程。

因此,在用户单击“下载图片”按钮后,我进入了回调,我调用了该方法来下载同一类中的图片。

thread.start_new_thread(self.images_download,(路径,页面)

这行不通。我让我的程序进入线程的唯一方法是使用

gtk.threads_init()

在开始任何线程之前。现在它下载了图片,但 GUI 仍然没有响应。我用谷歌搜索了这个并尝试将 gtk.threads_enter 和 gtk.threads_leave 放在线程周围,但它不起作用。

4

2 回答 2

12

你的问题有点模糊,如果没有参考你的实际代码,很难推测你做错了什么。

所以我会给你一些阅读的建议,然后根据经验进行疯狂的推测。

首先,您似乎认为您只能通过使用线程来保持 GUI 响应。这不是真的。您还可以异步编写代码,并在单线程应用程序中完成所有操作。 Twisted建立在这种编程模型之上。我最近发表了一篇博文,解释了我如何创建异步任务接口,以及 CLI 和 GTK+ 的示例运行器。您可以查看这些示例以了解如何异步实现任务,并且 UI 仍会更新。

其次,如果您出于某种原因更喜欢使用线程,则需要稍微了解 GTK+ 线程模型。

您应该首先阅读有关该主题的 PyGTK 常见问题解答条目,并且您可能会发现这篇博文也很容易理解。

现在,开始猜测。我猜您正在尝试从线程更新您的 GTK UI,并且没有正确处理锁定。如果是这种情况,您最好现在使用 gobject.idle_add() 将您想要从线程执行的所有 UI 更新推迟到主线程。这样,所有 UI 调用都将从主线程进行。在您的编程中,这是一个更容易遵循的思维模型。

一旦你觉得你真正了解线程和锁定模型,你可以考虑从你的线程更新 UI,但很容易错过threads_enter()/threads_leave()

于 2009-05-01T10:03:37.993 回答
1

您可以使用 gtk.gdk.threads_init() 以允许任何线程使用相应的 gtk.gdk.threads_enter() 和 gtk.gdk.theads_leave() 锁修改 UI,但是,这样做的问题是在 Windows 上运行良好。我已经在 Linux 上对其进行了测试并且性能相当不错,但是我没有运气让它在 win32 上运行。

=== 编辑 ===

我一直在浏览这个,你可以使用 gobject.io_add_watch 来检查你的套接字中是否有东西,抓住它然后更新 GUI。查看我的帖子: Sockets (and some other files) and PyGTK without threads。

于 2009-05-23T03:32:33.280 回答