python线程结束事件_实时绘制Matplotlib,PyQt和线程结束python崩溃

我有使用Matplotlib小部件的PyQT GUI应用程序。 GUI启动一个处理绘图到mpl小部件的新线程。我害怕现在通过从另一个线程访问matplotlib绘图组件来导致崩溃,现在运行到竞赛状态。

这基本上是,我的代码看起来像:

class Analyzer(QMainWindow, Ui_MainWindow):

def __init__(self, parent=None):

self.timer = QTimer()

super(Analyzer, self).__init__(parent)

self.setupUi(self)

self.background = self.mpl.canvas.copy_from_bbox(self.mpl.canvas.ax.bbox)

self.plotQueue = Queue.Queue()

self.plotterStarted = False

self.plotter = Plotter(self.mpl, self.plotQueue)

self.cam = Cam(self.plotQueue, self.textEdit)

...

class Ui_MainWindow(object):

def setupUi(self, MainWindow):

...

self.mpl = MplWidget(self.centralWidget)

...

class MplWidget(QtGui.QWidget):

"""Widget defined in Qt Designer"""

def __init__(self, parent = None):

QtGui.QWidget.__init__(self, parent)

self.canvas = MplCanvas()

...

class MplCanvas(FigureCanvas):

"""Class to represent the FigureCanvas widget"""

def __init__(self):

# setup Matplotlib Figure and Axis

self.fig = Figure()

self.ax = self.fig.add_subplot(111)

# initialization of the canvas

FigureCanvas.__init__(self, self.fig)

FigureCanvas.updateGeometry(self)

和绘图类:

class Plotter():

def __init__(self, mpl="", plotQueue=""):

self.mpl = mpl

self.background = self.mpl.canvas.copy_from_bbox(self.mpl.canvas.ax.bbox)

self.plotQueue = plotQueue

...

def start(self):

threading.Thread(target=self.run).start()

''' Real time plotting '''

def run(self):

while True:

try:

inputData = self.plotQueue.get(timeout=1)

# Go through samples

for samples in inputData:

self.line, = self.mpl.canvas.ax.plot(x, y, animated=True, label='Jee')

for sample in samples:

x.append(sample['tick'])

y.append(sample['linear'])

self.line.set_data(x,y)

self.mpl.canvas.ax.draw_artist(self.line)

self.mpl.canvas.blit(self.mpl.canvas.ax.bbox)

...

所以我通过MPL和plotQueue绘图仪类对象。 PlotQueue填充在处理来自外部hw的传入数据的Cam类中。绘图仪读取plotQueue,处理它并调用mpl的绘图。

但是,这是一个线程安全的方法来访问mpl?如果不是,我该怎么做?任何提示在此赞赏。

编辑1.

我加QTimer在主线程来处理绘制,如在意见提出。经过小小的调整后,我的工作得很好。

class Analyzer(...):

def __init__(self, parent=None):

QObject.connect(self.timer, SIGNAL("timeout()"), self.periodicCall)

def periodicCall(self):

self.plotter.draw()

def startButton(self):

self.timer.start(10)

非常感谢有用的意见。

+0

我记得读一些关于matplotlib有线程问题。_most_绘图命令应该非常快(并且可以使用blitting来解决大部分缓慢的情况),请在主线程中执行它们。 –

+0

谢谢,这正是我一直在想的,但在这种情况下,我的主线程是在实现GUI的Analyzer类中。分析器类有按钮等,所以如果我有一个循环读取队列和调用绘图,它会阻止整个应用程序。 我怎么能够在主线程中做循环? 我相信它必须是另一个线程做绘图,但如何做到线程安全?我可以使用同步,但除了我的plot方法之外,我应该在哪里放置另一个同步调用,它应该位于matplotlib库中的某个位置。 –

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值