如何在pygtk中运行单独的线程

时间:2013-06-15 08:43:50

标签: python multithreading textview gtk pygtk

我有一个pygtk应用程序,只要我的python脚本打开就会运行。与gtk.main()一起,我有一个在脚本开头启动的线程,它刷新了一个gtk.TextView()实例:

def listen(self):
    while True:
        print "refreshing"
        data = self.socket.recv(buffer_size)
        if data:
            self.txtBuffer.insert(self.txtBuffer.get_end_iter(), data + "\n")
            print data

thread.start_new_thread(self.listen, ())
self.set_up_gui() # gtk.main()

但是,当我运行程序时,gui会打开,但不会打印“刷新”文本,也不会在发送到套接字时打印任何数据。我试图使用glib.add_idle()来为这个程序进行线程化,但是当gui空闲时(这种情况不常见),它只会运行单独的线程。谢谢!

1 个答案:

答案 0 :(得分:2)

您正在从不同的线程访问文本缓冲区而没有任何同步,这是不受支持的。要解决此问题,请将self.txtBuffer.insert(...)替换为gobject.idle_add(lambda: self.txtBuffer.insert(...))。这告诉GUI线程在下一次主循环迭代时更新文本缓冲区,保证在没有显式同步的情况下工作。

您应该确保GUI线程没有被阻止,即它正在运行gtk.main(),并且只处理GUI更新,例如上面的textBuffer.insert。应该将长时间运行/阻塞任务委托给其他线程或进程,因为您的代码已经尝试过。实施此操作后,GUI更新将立即发生。

有关PyGTK和线程的更多详细信息,请参阅this answer