如何删除列出的“QGraphicsPathItem”对象以控制进程内存使用?

Posted

技术标签:

【中文标题】如何删除列出的“QGraphicsPathItem”对象以控制进程内存使用?【英文标题】:How to delete listed "QGraphicsPathItem" object to control process memory usage? 【发布时间】:2018-10-13 20:00:42 【问题描述】:

我想在QGraphicsView 中画一些路径。我想管理溺水路径。所以在path_ploter(double) 方法中,我画了一条路径并将对象的指针传递给PathItemList

我重绘了plot_fn() 插槽中的路径。我将此插槽连接到按钮。当我按下plot 按钮时,尽管在重绘路径之前删除了列表中的所有路径项指针,但进程内存使用量会增加。如果我在创建后立即删除列表中的指针,例如path_ploter(double)方法中的//delete PathItemList.back();,则进程使用内存不会增加。在这种情况下,不显示路径。为什么当我删除 plot 插槽中的指针时内存使用量会增加?怎么控制?

在头文件中:

#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_QtGuiApplication1.h"
#include <QGraphicsView>
#include <QGraphicsPathItem>
#include <QGraphicsLineItem>
#include <QtWidgets/QPushButton>

class QtGuiApplication1 : public QMainWindow

    Q_OBJECT

public:
    QtGuiApplication1(QWidget *parent = Q_NULLPTR);

private:
    Ui::QtGuiApplication1Class ui;
    QGraphicsView* qGraph;
    QGraphicsScene* scene;
    QGraphicsPathItem* pathItem = new QGraphicsPathItem();
    QList<QGraphicsPathItem *>PathItemList;
    void path_ploter(double);
private slots:
    void plot_fn();
;

在源文件中:

#include "QtGuiApplication1.h"

QtGuiApplication1::QtGuiApplication1(QWidget *parent)
    : QMainWindow(parent)

    ui.setupUi(this);

    //////////////
    qGraph = new QGraphicsView(ui.centralWidget);
    qGraph->setGeometry(QRect(0, 0, 300, 300));
    scene = new QGraphicsScene(qGraph);
    scene->setSceneRect(0, 0, 300, 300);
    qGraph->setScene(scene);    
    qGraph->show();
    ////////////
    QPushButton* btn_Ok = new QPushButton(ui.centralWidget);
    btn_Ok->setObjectName(QStringLiteral("btn_Ok"));
    btn_Ok->setGeometry(QRect(300, 300, 75, 23));
    btn_Ok->setText("Plot");
    connect(btn_Ok, SIGNAL(clicked()), this, SLOT(plot_fn()));
    //plot_fn();
    //path_ploter(1);


void QtGuiApplication1::path_ploter(double alpha)

    QPainterPath* myPath = new QPainterPath();
    QPolygon pol;

    QPen graphpen;
    graphPen.setColor(QColor(255, 0, 0, 255));
    graphPen.setWidth(2);


    QPoint pos;

    for (size_t i = 0; i < 100; i++)
    

        pos.setX(i);
        pos.setY(i*alpha);
        pol.append(pos);
    

    myPath->addPolygon(pol);
    pol.clear();


    pathItem = scene->addPath(*myPath, graphPen);
    PathItemList << pathItem;
    //delete PathItemList.back();
    pathItem = new QGraphicsPathItem();



void QtGuiApplication1::plot_fn()


    for (size_t i = 0; i < PathItemList.size(); i++)
    
        scene->removeItem(PathItemList.at(i));
    
    qDeleteAll(PathItemList.begin(), PathItemList.end());
    PathItemList.clear();

    for (size_t i = 0; i < 3; i++)
    
        path_ploter(i+1);

    


【问题讨论】:

【参考方案1】:

您的代码有几个错误:

为什么要创建QPainterPath 指针?由于addPath() 获取了该值的副本,因此无需永久保存该信息。

为什么要添加2个相同myPath的项目?,一个就够了,存到列表里。

为什么要创建 2 个 pathItem?创建一个带有addPath() 的pathItem 和另一个带有new QGraphicsPathItem 的pathItem,第二个不是必需的。

为什么在for循环中使用scene-&gt;addItem(PathItemList.back());,这没有意义。

请记住,创建指针时,您的任务是确保在关闭应用程序之前消除内存。

综合以上,代码应该如下:

void QtGuiApplication1::path_ploter(double alpha)

    QPainterPath myPath;
    QPolygonF pol;
    QPen graphPen;
    graphPen.setColor(QColor(255, 0, 0, 255));
    graphPen.setWidth(2);
    for (size_t i = 0; i < 100; i++)
        pol.append(QPointF(i, i*alpha));
    

    myPath.addPolygon(pol);
    QGraphicsPathItem *pathItem = scene->addPath(myPath, graphPen);
    PathItemList << pathItem;


void QtGuiApplication1::plot_fn()

    // Remove the item from the scene
    for(QGraphicsPathItem * pathItem: PathItemList)
        scene->removeItem(pathItem);
    
    // Delete the memory pointed by the pointers
    qDeleteAll(PathItemList.begin(), PathItemList.end());
    // Clean the container
    PathItemList.clear();
    for (size_t i = 0; i < 3; i++)
    
        path_ploter(i+1);
    

最后,建议你使用新的连接语法:

connect(btn_Ok, &QAbstractButton::clicked, this, &QtGuiApplication1::plot_fn);

【讨论】:

感谢您的宝贵时间和您的好建议。为您的问题的答案。 q2、q4 是我的错误并已编辑。我删除了 QPainterPath 并解决了问题。谢谢。

以上是关于如何删除列出的“QGraphicsPathItem”对象以控制进程内存使用?的主要内容,如果未能解决你的问题,请参考以下文章

PyQt5 QGraphicsPathItem 绘制一个电阻

如何列出过去已删除的 Fossil 存储库的所有文件?

如何删除会话中的所有对象,但名称在指定向量中列出的对象除外

如何在Linux上创建,列出和删除Docker容器

如何使用更改和删除事件在 firefox 和 chrome/chromium 上上传和列出目录

列出和删除存档中的目录