使用pyqtgraph异步绘制数据

时间:2017-12-13 09:09:34

标签: python pyqt python-multithreading pyqtgraph

我有一个模拟代码,我想用pyqtgraph为它添加诊断绘图。

模拟在Python类中实现。在伪代码中,

class Simulation:
    [...]
    '''
    Defines self.data, the stuff that needs plotting
    and self.done, which is False and becomese True once the simulation
    is over.
    '''

    def evolve(self):
        ''' takes care of updating self.data'''
        [...]
        self.done = True

    def get_data(self):
         return self.data

我想让它独立于绘图基础设施。

我要做的是创建一个绘图类,到目前为止我试图用python线程实现,它读取

import pyqtgraph as pg                                                         
import threading                                                               
from time import sleep                                                         
from pyqtgraph.Qt import QtGui

class Plot(threading.Thread):
    def __init__(self, source, target_fps=10):
        threading.Thread.__init__(self, daemon=True)
        self.source = source
        self.wait_time = 1. / target_fps

        self.win = pg.GraphicsWindow()
        self.plot = self.win.addPlot()
        self.curve = self.plot.plot()
        self.curve.setData(self.source.get_data())

    def run(self):
        while not self.source.done:
            self.curve.setData(self.source.get_data())
            sleep(self.wait_time)

其工作是偶尔轮询源类并更新绘图。那么我的__main__就像

那样
if __name__ == "__main__":
    sim = Simulation() # initialise simulation code
    plotter = Plot(sim)  # <- By commenting these three lines
    plotter.start()      # <- I fall back to a working simulation
    sim.evolve()         #
    plotter.join()       # <- without plotting diagnostics

当然之前的__main__不起作用,因为它缺少pyqtgraph所需的Qt事件循环,类似于pg.QtGui.QApplication.exec_(),它带来了不方便的副作用。在其之后阻止执行其余代码。如果我尝试将exec_()置于Plot.run()内,我会收到警告,告知必须在主线程中运行事件循环,并且不会显示绘图。

是否有一种解决方法可用于使绘图类工作而不会阻止模拟的执行?我不想触及Simulation课程。

0 个答案:

没有答案