2016-12-05 3 views
1

Я построил графический интерфейс Matplotlib с Qt Designer в основном после this tutorial. Я использую python 3.5.2 и pyqt 5.6.0. Код, который вы видите ниже, работает. Однако при изменении графиков память, используемая моей системой, увеличивается, по крайней мере, в соответствии с Windows 10 Task Manager. Чтобы воссоздать это немного лучше, можно увеличить количество случайных значений, используемых в командах графика. Кажется, что команда self.canvas.close() внутри функции rmmppl недостаточно, чтобы фактически освободить используемую память.Утечка памяти при встраивании matplotlib в PyQt5 GUI

Как предотвратить увеличение использования памяти?

редактировать: вот Screenshot графического интерфейса

from PyQt5 import QtCore, QtGui, QtWidgets 
from matplotlib.figure import Figure 
from matplotlib.backends.backend_qt5agg import (
FigureCanvasQTAgg as FigureCanvas, 
NavigationToolbar2QT as NavigationToolbar) 
import window 
import numpy as np 


class Plotter(QtWidgets.QMainWindow, window.Ui_MainWindow): 
    def __init__(self): 
     super(Plotter, self).__init__() 
     self.setupUi(self) 
     self.fig_dict = {}  
     self.mplfigs.itemClicked.connect(self.changefig) 

    def addmpl(self, fig): 
     self.canvas = FigureCanvas(fig) 
     self.mplvl.addWidget(self.canvas) 
     self.canvas.draw() 
     self.toolbar = NavigationToolbar(self.canvas,self.mplwindow, coordinates = True) 
     self.mplvl.addWidget(self.toolbar) 

    def rmmppl(self): 
     self.mplvl.removeWidget(self.canvas) 
     self.canvas.close() 
     self.mplvl.removeWidget(self.toolbar) 
     self.toolbar.close() 

    def addfig(self, name, fig): 
     self.fig_dict[name]=fig 
     self.mplfigs.addItem(name) 

    def changefig(self,item): 
     text = item.text() 
     self.rmmppl() 
     self.addmpl(self.fig_dict[text]) 



def main(): 
    import sys 

    fig1 = Figure() 
    ax1f1= fig1.add_subplot(111) 
    ax1f1.plot(np.random.rand(5)) 

    fig2 = Figure() 
    ax1f2 = fig2.add_subplot(121) 
    ax1f2.plot(np.random.rand(5)) 
    ax1f2 = fig2.add_subplot(122) 
    ax1f2.plot(np.random.rand(10))  

    app=QtWidgets.QApplication(sys.argv) 
    main=Plotter() 
    main.addmpl(fig1) 
    main.addfig('Figure 1', fig1) 
    main.addfig('Figure 2', fig2) 
    main.show() 

    sys.exit(app.exec_()) 


if __name__ == '__main__': 
    main() 

window.py, который является структурой Basic GUI:

from PyQt5 import QtCore, QtGui, QtWidgets 

class Ui_MainWindow(object): 
    def setupUi(self, MainWindow): 
     MainWindow.setObjectName("MainWindow") 
     MainWindow.resize(640, 432) 
     self.centralwidget = QtWidgets.QWidget(MainWindow) 
     self.centralwidget.setObjectName("centralwidget") 
     self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget) 
     self.horizontalLayout.setObjectName("horizontalLayout") 
     self.mplwindow = QtWidgets.QWidget(self.centralwidget) 
     sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) 
     sizePolicy.setHorizontalStretch(0) 
     sizePolicy.setVerticalStretch(0) 
     sizePolicy.setHeightForWidth(self.mplwindow.sizePolicy().hasHeightForWidth()) 
     self.mplwindow.setSizePolicy(sizePolicy) 
     self.mplwindow.setObjectName("mplwindow") 
     self.mplvl = QtWidgets.QVBoxLayout(self.mplwindow) 
     self.mplvl.setContentsMargins(0, 0, 0, 0) 
     self.mplvl.setObjectName("mplvl") 
     self.horizontalLayout.addWidget(self.mplwindow) 
     self.mplfigs = QtWidgets.QListWidget(self.centralwidget) 
     sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Expanding) 
     sizePolicy.setHorizontalStretch(0) 
     sizePolicy.setVerticalStretch(0) 
     sizePolicy.setHeightForWidth(self.mplfigs.sizePolicy().hasHeightForWidth()) 
     self.mplfigs.setSizePolicy(sizePolicy) 
     self.mplfigs.setMaximumSize(QtCore.QSize(200, 16777215)) 
     self.mplfigs.setMinimumSize(QtCore.QSize(200, 0)) 
     self.mplfigs.setObjectName("mplfigs") 
     self.horizontalLayout.addWidget(self.mplfigs) 
     MainWindow.setCentralWidget(self.centralwidget) 
     self.menubar = QtWidgets.QMenuBar(MainWindow) 
     self.menubar.setGeometry(QtCore.QRect(0, 0, 640, 31)) 
     self.menubar.setObjectName("menubar") 
     MainWindow.setMenuBar(self.menubar) 
     self.statusbar = QtWidgets.QStatusBar(MainWindow) 
     self.statusbar.setObjectName("statusbar") 
     MainWindow.setStatusBar(self.statusbar) 

     self.retranslateUi(MainWindow) 
     QtCore.QMetaObject.connectSlotsByName(MainWindow) 

    def retranslateUi(self, MainWindow): 
     _translate = QtCore.QCoreApplication.translate 
     MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) 

ответ

3

Я выполнил свой код на Linux, и я наблюдали такой же утечка памяти. Попробуйте с этим:

Импорт сборщик мусора с:

import gc 

Затем измените метод rmmppl:

def rmmppl(self): 
    self.canvas.close() 
    self.canvas.deleteLater() 
    self.toolbar.close() 
    self.toolbar.deleteLater() 
    gc.collect() 

Вот документация deleteLater QObject Class Documentation

+0

это решение решает мою проблему , благодаря! –

Смежные вопросы