QT QPixmap QImage内存泄漏
无论是在代码中还是在UI中设置icon都会产生内存泄漏
大概看了下,好像是QPixmap的data_ptr的引用计数,到不了1/0(查看引用计数,释放后,理论上应回到1)
试了下,仅以下两种方式不会产生内存泄漏:
1、从 XPM加载:
img = QPixmap(result); //result为 static const char *result[] = {。。。。}
或
ui.label->setPixmap(QPixmap(result));
2、现场绘制:
img = QPixmap(16, 16);
img.fill(Qt::transparent);
QPainter painter(&img);
painter.drawLine(1, 1, 15, 15);
。。。
painter.end();
ui.label->setPixmap(img);
但是,使用XPM,图片的质量太差
png
xpm
所以决定自己绘制。
步骤一、使用代码生成自定义图片的数据文件:
w(ushort)h(ushort)bytesperpixel(uchar)+若干RGBA数据
例:
16(ushort)16(ushort)4(uchar)+{uint32(RGBA)*16*16}
步骤二、加载、显示
CLeeBuffer.h 自定义图片数据的存取类
#include <QByteArray>
class CLeeBuffer
{
public:
CLeeBuffer() {}
~CLeeBuffer() {}
CLeeBuffer& Store(char val) {
m_data.append(1, val);
return *this;
}
CLeeBuffer& Store(uchar val) {
m_data.append(1, (char)val);
return *this;
}
CLeeBuffer& Store(ushort val) {
m_data.append((const char*)&val, 2);
return *this;
}
CLeeBuffer& Store(short val) {
m_data.append((const char*)&val, 2);
return *this;
}
CLeeBuffer& Store(uint val) {
m_data.append((const char*)&val, 4);
return *this;
}
CLeeBuffer& Store(int val) {
m_data.append((const char*)&val, 4);
return *this;
}
CLeeBuffer& Store(void* pBuf, int len) {
m_data.append((const char*)pBuf, len);
return *this;
}
CLeeBuffer& Store(QByteArray val) {
m_data.append(val);
return *this;
}
bool Read(int& nPos, char& val) {
if (nPos + sizeof(val) > m_data.size())
return false;
auto pBuf = m_data.constData();
memcpy(&val, pBuf + nPos, sizeof(val));
nPos += sizeof(val);
return true;
}
bool Read(int& nPos, uchar& val) {
if (nPos + sizeof(val) > m_data.size())
return false;
auto pBuf = m_data.constData();
memcpy(&val, pBuf + nPos, sizeof(val));
nPos += sizeof(val);
return true;
}
bool Read(int& nPos, ushort& val) {
if (nPos + sizeof(val) > m_data.size())
return false;
auto pBuf = m_data.constData();
memcpy(&val, pBuf + nPos, sizeof(val));
nPos += sizeof(val);
return true;
}
bool Read(int& nPos, short& val) {
if (nPos + sizeof(val) > m_data.size())
return false;
auto pBuf = m_data.constData();
memcpy(&val, pBuf + nPos, sizeof(val));
nPos += sizeof(val);
return true;
}
bool Read(int& nPos, uint& val) {
if (nPos + sizeof(val) > m_data.size())
return false;
auto pBuf = m_data.constData();
memcpy(&val, pBuf + nPos, sizeof(val));
nPos += sizeof(val);
return true;
}
bool Read(int& nPos, int& val) {
if (nPos + sizeof(val) > m_data.size())
return false;
auto pBuf = m_data.constData();
memcpy(&val, pBuf + nPos, sizeof(val));
nPos += sizeof(val);
return true;
}
bool Read(int& nPos, void* pBuf, int len) {
if (nPos + len > m_data.size())
return false;
auto pBuf_ = m_data.constData();
memcpy(pBuf, pBuf_ + nPos, len);
nPos += len;
return true;
}
QByteArray getData() {
return m_data;
}
private:
QByteArray m_data;
};
QLeePixmap.h
#include "CLeeBuffer.h"
#include <QPixmap>
#include <QFile>
#include <QString>
#include <QPainter>
#include <QPen>
class QLeePixmap
{
public:
QLeePixmap() {}
QLeePixmap(QString sFile) {
load(sFile);
}
void load(QString sFile) {
union {
int IntVal;
struct {
uchar b, g, r, a;
}Color;
}Color32;
QFile mFile(sFile);
if (mFile.open(QIODevice::ReadOnly)) {
CLeeBuffer leeBuf;
leeBuf.Store(mFile.readAll());
mFile.close();
ushort w = 0, h = 0;
uchar bytesPerPixel = 0;
int nPos = 0;
leeBuf.Read(nPos, w);
leeBuf.Read(nPos, h);
leeBuf.Read(nPos, bytesPerPixel);
m_pixmap = QPixmap(w, h);
m_pixmap.fill(Qt::transparent);
QPainter painter(&m_pixmap);
QPen pen;
for (ushort row = 0; row < h; row++) {
for (ushort col = 0; col < w; col++) {
if (!leeBuf.Read(nPos, Color32.IntVal)) {
}
pen.setColor(QColor(Color32.Color.r, Color32.Color.g, Color32.Color.b, Color32.Color.a));
painter.setPen(pen);
painter.drawPoint(col, row);
}
}
painter.end();
}
}
QPixmap& getPixmap() {
return m_pixmap;
}
private:
QPixmap m_pixmap;
};
使用:
QLeePixmap m_img;//.h
//.cpp
m_img.load(QString::fromLocal8Bit("。。。。\\img_connected.sim")); ui.label->setPixmap(m_img.getPixmap());
注 对微小尺寸的图片适用,对大尺寸不太适用——因为生成的文件大小近似 BMP格式的文件大小

浙公网安备 33010602011771号