QThread在mac上的pyqtgraph中被破坏
Posted
技术标签:
【中文标题】QThread在mac上的pyqtgraph中被破坏【英文标题】:QThread destroyed in pyqtgraph on mac 【发布时间】:2014-04-29 07:28:51 【问题描述】:我正在尝试在 MacOS X 上使用 Anaconda python 运行我找到的这个简单示例 here。
import pyqtgraph as pg
import time
plt = pg.plot()
def update(data):
plt.plot(data, clear=True)
class Thread(pg.QtCore.QThread):
newData = pg.QtCore.Signal(object)
def run(self):
while True:
data = pg.np.random.normal(size=100)
# do NOT plot data from here!
self.newData.emit(data)
time.sleep(0.05)
thread = Thread()
thread.newData.connect(update)
thread.start()
但我不断得到:
QThread: Destroyed while thread is still running
【问题讨论】:
【参考方案1】:您的程序将立即退出,因为您在启动线程后没有给它任何可做的事情。您看到的错误是因为线程很惊讶主线程没有它就退出了。
解决方法:在脚本末尾添加QtGui.QApplication.exec_()
。或者,如果您有 PyQt(不是 PySide),则可以改为从交互式 python 提示符运行。
【讨论】:
【参考方案2】:pyqtgraph.plot
方法对我来说似乎有问题(无论如何,我无法让它产生任何有用的输出,但也许我做错了什么)。
但是,如果我创建一个PlotWidget
并“手动”设置应用程序,一切都会按预期工作:
import pyqtgraph as pg
import numpy as np
import time
app = pg.QtGui.QApplication([])
window = pg.QtGui.QMainWindow()
plot = pg.PlotWidget()
window.setCentralWidget(plot)
window.show()
def update(data):
plot.plot(data, clear=True)
class Thread(pg.QtCore.QThread):
newData = pg.QtCore.Signal(object)
def run(self):
while True:
data = pg.np.random.normal(size=100)
# do NOT plot data from here!
self.newData.emit(data)
time.sleep(0.05)
thread = Thread()
thread.newData.connect(update)
thread.start()
app.exec_()
【讨论】:
ekhumoro:请在另一个 SO 问题或 pyqtgraph 邮件列表中分享您使用 pg.plot() 的经验。 @Luke。我现在无法重现我之前的问题,所以我一定是做错了什么,不知何故。没关系...【参考方案3】:当您调用QThread.start()
时,该函数会立即返回。会发生什么,
-
线程 #1 - 创建新线程 #2
线程 #2 已创建
线程 #1 重新获得控制权并运行。
线程 #1 死亡或
thread
变量被 GC(垃圾收集器)清理 - 我假设第二种情况不应该发生
要解决这个问题,不要让主线程死掉。在它死之前,清理所有线程。
http://pyqt.sourceforge.net/Docs/PyQt4/qthread.html#wait
bool QThread.wait (self, int msecs = ULONG_MAX)
阻塞线程直到满足以下任一条件:
与此 QThread 对象关联的线程已完成执行(即,当它从 run() 返回时)。该函数将返回 如果线程已完成,则为 true。如果线程也返回 true 尚未开始。 time 毫秒已经过去。如果时间为 ULONG_MAX(默认值),则等待永远不会超时(线程必须从 run() 返回)。 如果等待超时,此函数将返回 false。这提供了与 POSIX pthread_join() 类似的功能 功能。
所以,将thread.wait()
添加到您的代码中。
注意:您需要确保您的线程退出。照原样,它永远不会退出。
【讨论】:
他没有事件循环 关键是,你在退出之前加入线程。即使主事件循环退出,你也必须加入你的线程,否则你会冒他所问的风险 我明白你的意思。但是:如果事件循环已启动,那么似乎没有必要等待线程。我不确定为什么,因为在事件循环退出后线程继续运行.. 有一个竞争条件,线程已启动但其线程存储未初始化 - 这就是导致来自 Qt 的错误消息的原因。然而,在离开主执行之前不等待线程完成可能会导致其他地方出现问题。在我的回答中,我假设任何使用 Qt 的人都已经知道诸如 QCoreApplication::exec() 之类的事情。它只出现在每个代码示例中:)以上是关于QThread在mac上的pyqtgraph中被破坏的主要内容,如果未能解决你的问题,请参考以下文章
在 MAC 上使用 anaconda python 的 Pyqtgraph 给出 nib 错误
pyqtgraph:如何绘制时间序列(x 轴上的日期和时间)?