【发布时间】:2014-01-31 00:39:53
【问题描述】:
堆栈溢出。再一次,我在急需的时候来找你,在精神错乱的边缘摇摇欲坠。这个问题——从标题中可以看出——是我在这里看到的其他几个问题的合并。
我有一个 PyQt 应用程序,我想将 stdout 和 stderr 流重新路由到我的 GUI 中的 QTextEdit没有延迟。
最初,我找到了以下堆栈溢出的答案: https://stackoverflow.com/a/17145093/629404
这很完美,但有一个警告:如果在 CPU 处理相对较长的方法时多次更新 stdout 或 stderr,当主线程返回应用程序循环时,所有更新都会同时显示。不幸的是,我有一些方法最多需要 20 秒才能完成(与网络相关),因此应用程序变得无响应 - 并且 QTextEdit 不会更新 - 直到它们完成。
为了解决这个问题,我将所有的 GUI 处理委托给主线程,并且我一直在生成第二个线程来处理更长的网络操作,使用 pyqtSignals 来通知主线程何时工作完成并传回结果。当我开始测试以这种方式编写的代码时,python 解释器立即开始崩溃,没有任何警告。
这是非常令人沮丧的地方:Python 崩溃了,因为 - 使用上面包含的链接中的类 - 我已将 sys.stdout/err 流分配给 QTextEdit 小部件; PyQt 小部件不能从除应用程序线程之外的任何线程进行修改,并且由于对 stdout 和 stderr 的更新来自我创建的辅助工作线程,因此它们违反了此规则。我已注释掉我重定向输出流的代码部分,果然,程序运行没有错误。
这让我回到了原点,让我陷入了混乱的境地;假设我继续在主线程中处理与 GUI 相关的操作,并在辅助线程中处理计算和更长的操作(我已经明白这是防止应用程序在用户触发事件时阻塞的最佳方法),我怎么能将两个线程的 Stdout 和 Stderr 重定向到 QTextEdit 小部件?上面链接中的类在主线程中工作得很好,但是当更新来自第二个线程时,由于上述原因,杀死了 python。
【问题讨论】:
标签: python multithreading thread-safety pyqt stdout