根据我对twisted的理解,在reactor线程中运行的任何东西都不应该阻塞。所有的阻塞活动都应该委托给其他线程,以便在执行完回调后将其返回到reactor线程中。在
那么这也适用于gtk吗?例如,如果连接。。。失败。我需要:
def connectionFailed(self, reason):
dlg = gtk.MessageDialog(type=gtk.MESSAGE_ERROR,
buttons=gtk.BUTTONS_CLOSE,
message_format="Could not connect to server:\n%s" % (
reason.getErrorMessage()))
dlg.run()
或者:
^{pr2}$或者:
def connectionFailed(self, reason):
def bloogedy():
dlg = gtk.MessageDialog(type=gtk.MESSAGE_ERROR,
buttons=gtk.BUTTONS_CLOSE,
message_format="Could not connect to server:\n%s" % (
reason.getErrorMessage()))
dlg.run()
reactor.callInThread(bloogedy)
是吗?在
编辑:哦,好吧,后两个真的搞砸了。所以我想答案是第一个。我的问题是:为什么?看起来这会阻塞反应器线程。
你的问题实际上与线程和gui没有任何关系。您应该始终使用来自同一线程的Twisted和GTK:没有必要另外做。在
您的问题是您正在使用
gtk.Dialog.run()
。不管是否扭曲,这是一个绝对不应该使用的API。它运行一个可重入的主循环,这会导致当前事件处理程序阻塞,但允许其他事件处理程序在堆栈下一层执行。GTK对可重入的主循环有很好的支持,但是Twisted没有(这没关系,因为正如我所说,您不应该使用它们)。在在消息对话框.run不管怎样,在一个线程中都不能工作,所以你实际上没有这个选项。它将导致不可预测的行为,从而导致应用程序行为异常或崩溃。GTK对线程有很好的支持,但是有些事情你永远不应该用线程来做,因为它没有任何意义,这就是其中之一。在
如果您正在处理的代码没有进行任何处理,但只想等待某件事情发生(例如等待用户按对话框上的按钮),则应该使用返回} ”。您可以使用它来连接一个非常简单的函数,该函数用一个对话框显示您的消息,并在消息完成时返回一个
Deferred
s的函数,而不是线程。如果发生这种情况,gtk.Dialog
s将在它们被响应的点发出一个信号:“^{Deferred
。下面是一个例子:虽然不推荐也不受支持,但是对于Twisted 10.x,下面的代码似乎可以继续使用gtk.main公司() / 对话.运行()
根据我使用Gtk+的经验,最好的选择是在单独的线程中运行GUI。您可以通过在Gtk+主循环中运行函数(通过idle_add函数)与GUI线程进行连接。我不知道reactor,但是从您的例子来看,从GUI进行通信的相同方式是可能的。在
例如,像这样(抱歉,我还没有测试代码):
(除此之外,gtk.main公司必须在自己的线程上运行)
这将在Gtk+线程中运行frob函数,并且不会阻塞reactor线程。在
这将在单独的线程中启动Gtk+:
^{pr2}$如果需要一些复杂的GUI交互,则必须使用continuation-passing style进行编程
编辑:添加了在单独线程中运行Gtk+的示例
相关问题 更多 >
编程相关推荐