避免Qpainter内存泄漏

时间:2017-10-26 21:20:36

标签: qt memory-leaks qpainter

我在QPixmap上使用QPainter时遇到内存泄漏问题。我需要在地图上设置大约250000个点(地图点)。它们中的每一个都共享相同的图标,但具有特定的标签。我将所有这些点添加到同一层。

这是我的代码:

void Gspv::addFixes() // waypoints layer
{
    waypoints = new GeometryLayer("Waypoints", mapadapter);
    mc->addLayer(waypoints);

    //Icon
    QPixmap icone(38,38);
    icone.fill(Qt::transparent);
    QPainter *paint = new QPainter(&icone);
    paint->setRenderHint(QPainter::Antialiasing);
    paint->setBrush(Qt::cyan);
    paint->setPen(Qt::black);
    static const QPoint triangle[3] = {
        QPoint(15,0),
        QPoint(3, 20),
        QPoint(27,20)
    };
    paint->drawPolygon(triangle, 3);
    delete paint;

    //Check file
    QFile file(QCoreApplication::applicationDirPath() + "/data/Waypoints.txt");
    if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        QMessageBox::information(0, "erreur lecture fichier : " + file.fileName(), file.errorString());
        return;
    }

    //Parsing file
    QTextStream in(&file);
    while(!in.atEnd()) {
        QString line = in.readLine();
        QStringList fields = line.split(",");
        QString str = fields.at(1);
        double latitude = str.toDouble();
        str = fields.at(2);
        double longitude = str.toDouble();
        str = fields.at(0);

        addCode(icone,str); // Prob here

        //Add current point to layer
        Point* pointCourant = new Point(longitude, latitude, icone, str);
        pointCourant->setBaselevel(10);
        pointCourant->setMaxsize(QSize(38, 38));
        waypoints->addGeometry(pointCourant);

    }

    file.close();
}


//Add code to QPixmap
void Gspv::addCode(QPixmap &pm, QString &code)
{
    QPainter pmp(&pm);
    pmp.setPen(Qt::black);
    pmp.setFont(QFont("ArialBold",9));
    pmp.eraseRect(0,20,38,15);
    pmp.drawText(0,32,code);
}

一切都按预期工作,但它会导致严重的内存泄漏。 问题是在while循环中添加代码。无论我做什么(在addfixes方法中添加代码或在addCode中使用特定的addcode),我都会遇到内存泄漏。

即使代码仅缩减为:

void Gspv::addCode(QPixmap &pm, QString &code)
{
    QPainter pmp(&pm);
    // here it does nothing !
}

内存泄漏是。无论语句是静态的还是动态的,结果都是一样的。

如果不添加代码,内存使用量约为152 Mo,这足够低。通过添加这个简单的代码,它会使内存不足。

我在QPainter和内存泄漏上阅读了很多帖子,但我无法处理它。

你会得到帮助吗?

提前致谢。

1 个答案:

答案 0 :(得分:0)

@AlexanderVX 根据您的评论我改变了我的代码。这是新结构。

这个addFixes方法:

void Gspv::addFixes() // waypoints layer
{

...
    addCode(icone,str); // Prob here
...
}

成为这个:

void Gspv::addFixes() // waypoints layer
{
...
    //Add code within icon
    paint = new QPainter(&icone);
    QGraphicsItem *item = new GenIcone("wayPoint", str, paint);
    delete paint;
...
}

AddCode方法已被全新的GenIcon类取代。

·H

#ifndef GENICONE_H
#define GENICONE_H

//#include <QPixmap>
#include <QGraphicsItem>
#include <QPainter>

class GenIcone : public QGraphicsItem
{
public:
    GenIcone(const QString icone, QString code, QPainter *painter);
    QRectF boundingRect() const Q_DECL_OVERRIDE;
    QPainterPath shape() const Q_DECL_OVERRIDE;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget) Q_DECL_OVERRIDE;

    QPainter m_painter;

private :
    QString m_icone;
    QString m_code;
};

#endif // GENICONE_H

的.cpp

#include "genicone.h"
#include <QtWidgets>
#include <QWidget>
#include <QStyleOptionGraphicsItem>

GenIcone::GenIcone(const QString icone, QString code, QPainter *painter)
{
    this->m_icone = icone;
    this->m_code = code;

    setAcceptHoverEvents(true);
    QStyleOptionGraphicsItem opt;
    QWidget w;

    paint(painter,&opt,&w);
}


void GenIcone::paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget)
{
    Q_UNUSED(widget);
    Q_UNUSED(item);

    //Draw code within icon

    if (m_icone== "wayPoint") {
        painter->setFont(QFont("ArialBold",10));
        painter->eraseRect(0,20,50,18);
        painter->drawText(1,32,m_code);
        painter->end();
    }
}

QRectF GenIcone::boundingRect() const 
{
    ...
}

QPainterPath GenIcone::shape() const
{
    ...
}

所以,它有效,但是尽管油漆超载,我仍然会得到内存泄漏。我该怎么做才能改进我的代码?

感谢您的帮助