【问题标题】:QThread destroyed in pyqtgraph on macQThread在mac上的pyqtgraph中被破坏
【发布时间】: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

【问题讨论】:

    标签: python qt qthread pyqtgraph


    【解决方案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. 线程 #1 - 创建新线程 #2
      2. 线程 #2 已创建
      3. 线程 #1 重新获得控制权并运行。
      4. 线程 #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() 之类的事情。它只出现在每个代码示例中:)
      猜你喜欢
      • 2020-02-15
      • 2013-01-12
      • 1970-01-01
      • 2012-09-28
      • 1970-01-01
      • 2014-10-23
      • 2011-06-23
      • 2023-04-02
      • 1970-01-01
      相关资源
      最近更新 更多