在PyQt GUI中嵌入和更新matplotlib图时发生内存泄漏 - python

我试图将matplotlib图嵌入到PyQt GUI主窗口中,该图每秒更新一次。

在我的程序中,我每秒通过threading.Timer函数使用timer调用更新函数。我有一个问题:我的程序每秒增长一次-每4秒以大约1k的速度增长。我最初的想法是append函数(在update_figure中返回新数组)不会删除旧数组?这可能是我遇到问题的原因吗?

def update_figure(self):
    self.yAxis = np.append(self.yAxis, (getCO22()))
    self.xAxis = np.append(self.xAxis, self.i)
    # print(self.xAxis)
    if len(self.yAxis) > 10:
        self.yAxis = np.delete(self.yAxis, 0)

    if len(self.xAxis) > 10:
        self.xAxis = np.delete(self.xAxis, 0)

    self.axes.plot(self.xAxis, self.yAxis, scaley=False)
    self.axes.grid(True)

    self.i = self.i + 1

    self.draw()

这是我的计时器功能-这是通过单击PyQt GUI中的按钮触发的,然后调用它,如您所见:

def timer(self):
    getCH4()
    getCO2()
    getConnectedDevices()
    self.dc.update_figure()
    t = threading.Timer(1.0, self.timer)
    t.start()

编辑:我无法发布我的整个代码,因为它需要很多.dll包含。因此,我将尝试解释该程序的作用。

在我的GUI中,我想显示一段时间内的CO2值。我的get_co22函数只返回一个浮点值,我100%确信这可以正常工作。使用上面显示的计时器,我想继续向matplotlib图添加一个值-Axes对象对我来说是self.axes可用的。我尝试绘制数据的最后10个值。

编辑2:在一些discussion in chat之后,我尝试将对update_figure()的调用放在while循环中,并仅使用一个线程对其进行调用,并且能够制作出一个最小的示例http://pastebin.com/RXya6Zah。这将代码的结构更改为调用update_figure()到以下内容:

def task(self):
    while True:
        ui.dc.update_figure()
        time.sleep(1.0)

def timer(self):
    t = Timer(1.0, self.task())
    t.start()

但是现在程序在大约5次迭代后崩溃了。

参考方案

问题绝对不在于您如何附加到numpy数组或将其截断。
这里的问题是您的线程模型。很难将计算循环与GUI控制循环集成在一起。
从根本上讲,您需要GUI线程来控制何时调用更新代码(必要时产生一个新线程来处理它)-

您的代码不会阻止GUI更新,
GUI更新不会阻止您的代码执行和
您不会产生包含多个对象副本的线程负载(这可能是内存泄漏的来源)。

在这种情况下,由于主窗口是由PyQt4控制的,因此您想使用QTimer(请参见simple example here)
因此-将您的timer代码更改为

def task(self):
    getCH4()
    getCO2()
    getConnectedDevices()
    self.dc.update_figure()

def timer(self):
    self.t = QtCore.QTimer()
    self.t.timeout.connect(self.task)
    self.t.start(1000)

这应该工作。保持对QTimer的引用是必不可少的-因此self.t = QtCore.QTimer()而不是t = QtCore.QTimer(),否则QTimer对象将被垃圾回收。

注意:
这是long thread in chat的概述,它用于阐明问题并通过几种可能的解决方案进行工作。特别是-OP设法在此处模拟了一个更简单的可运行示例:http://pastebin.com/RXya6Zah
完整的可运行示例的固定版本在这里:http://pastebin.com/gv7Cmapr
上面有相关的代码和解释,但是这些链接可能会帮助想要复制/解决问题的任何人。请注意,它们需要安装PyQt4

Python GPU资源利用 - python

我有一个Python脚本在某些深度学习模型上运行推理。有什么办法可以找出GPU资源的利用率水平?例如,使用着色器,float16乘法器等。我似乎在网上找不到太多有关这些GPU资源的文档。谢谢! 参考方案 您可以尝试在像Renderdoc这样的GPU分析器中运行pyxthon应用程序。它将分析您的跑步情况。您将能够获得有关已使用资源,已用缓冲区,不同渲染状态上…

Python sqlite3数据库已锁定 - python

我在Windows上使用Python 3和sqlite3。我正在开发一个使用数据库存储联系人的小型应用程序。我注意到,如果应用程序被强制关闭(通过错误或通过任务管理器结束),则会收到sqlite3错误(sqlite3.OperationalError:数据库已锁定)。我想这是因为在应用程序关闭之前,我没有正确关闭数据库连接。我已经试过了: connectio…

Python exchangelib在子文件夹中读取邮件 - python

我想从Outlook邮箱的子文件夹中读取邮件。Inbox ├──myfolder 我可以使用account.inbox.all()阅读收件箱,但我想阅读myfolder中的邮件我尝试了此页面folder部分中的内容,但无法正确完成https://pypi.python.org/pypi/exchangelib/ 参考方案 您需要首先掌握Folder的myfo…

Matplotlib-固定x轴缩放比例和自动缩放y轴 - python

我只想绘制部分数组,固定x部分,但让y部分自动缩放。我尝试如下所示,但是它不起作用。有什么建议么?import numpy as np import matplotlib.pyplot as plt data=[np.arange(0,101,1),300-0.1*np.arange(0,101,1)] plt.figure() plt.scatter(da…

python-docx应该在空单元格已满时返回空单元格 - python

我试图遍历文档中的所有表并从中提取文本。作为中间步骤,我只是尝试将文本打印到控制台。我在类似的帖子中已经看过scanny提供的其他代码,但是由于某种原因,它并没有提供我正在解析的文档的预期输出可以在https://www.ontario.ca/laws/regulation/140300中找到该文档from docx import Document from…