python - twisted + gtk : should I run GUI things in threads, 还是在 react 器线程中?

标签 python multithreading gtk twisted pygtk

根据我对 twisted 的理解,在 react 器线程中运行的任何东西都不应阻塞。所有阻塞事件都应委托(delegate)给其他线程,以便在它们完成时将回调触发回 react 器线程。

那么这也适用于 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()

或:

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()))
    reactor.callInThread(dlg.run)

或:

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)

?

编辑:哦好吧,后两个真的搞砸了。所以我想答案是第一个。那么我的问题是:为什么?看起来这会阻塞 react 器线程。

最佳答案

您的问题实际上与线程和 GUI 没有任何关系。您应该始终在同一个线程中使用 Twisted 和 GTK:没有必要做其他事情。

您的问题是您正在使用 gtk.Dialog.run()。这是一个你永远不应该使用的 API,无论 Twisted 与否。它运行一个可重入的主循环,这会导致您当前的事件处理程序阻塞,但允许其他事件处理程序执行堆栈中的下一层。 GTK 对可重入主循环有很好的支持,但 Twisted 没有(这没关系,因为就像我说的,你不应该使用它们)。

无论如何,MessageDialog.run 不会在线程中运行,因此您实际上没有该选项。它会导致不可预知的行为,从而导致您的应用程序行为异常或崩溃。 GTK 对线程有很好的支持,但是有些事情你永远不应该用线程来做,因为它没有任何意义,这就是其中之一。

如果你正在处理不做任何处理的代码,只是想等待某事发生(比如等待用户按下对话框上的按钮),你应该使用返回 的函数延迟,而不是线程。碰巧的是,gtk.Dialogs 将在它们被响应时发出一个信号:“response”。您可以使用它来连接一个非常简单的函数,该函数通过对话框显示消息并在完成时返回 Deferred。这是一个例子:

def showMessage(text):
    mdlg = gtk.MessageDialog(type=gtk.MESSAGE_INFO,
                             buttons=gtk.BUTTONS_CLOSE,
                             message_format=text)
    result = Deferred()
    def response(dialog, response_id):
        mdlg.destroy()
        result.callback(response_id)
        return False
    mdlg.connect("response", response)
    mdlg.show_all()
    return result

关于python - twisted + gtk : should I run GUI things in threads, 还是在 react 器线程中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3504739/

相关文章:

python - `pipenv install -e .` 有什么作用以及如何使用它?

python - 在 Python 的子列表中查找单词序列

javascript - 并行 JavaScript 代码

c - 使用 GTK 回调函数提交数组

c - 我如何理解以下内容的含义?

java - Swing GTK L&F 标题栏上的额外按钮

Python - 在本地变量中存储实例变量以避免 "self"的错误做法?

python - autoenv 甚至在子文件夹中执行

java - 如何使用安全线程对象作为值初始化hashTable?

Python多处理问题