惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
P
Proofpoint News Feed
G
Google Developers Blog
B
Blog
Engineering at Meta
Engineering at Meta
阮一峰的网络日志
阮一峰的网络日志
The Register - Security
The Register - Security
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 叶小钗
The Cloudflare Blog
The Hacker News
The Hacker News
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
雷峰网
雷峰网
F
Fortinet All Blogs
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
H
Hackread – Cybersecurity News, Data Breaches, AI and More
酷 壳 – CoolShell
酷 壳 – CoolShell
Last Week in AI
Last Week in AI
T
Threat Research - Cisco Blogs
A
About on SuperTechFans
量子位
Recorded Future
Recorded Future
博客园 - 三生石上(FineUI控件)
H
Help Net Security
Help Net Security
Help Net Security
P
Palo Alto Networks Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
T
Troy Hunt's Blog
W
WeLiveSecurity
V
Vulnerabilities – Threatpost
T
The Exploit Database - CXSecurity.com
Know Your Adversary
Know Your Adversary
Apple Machine Learning Research
Apple Machine Learning Research
Scott Helme
Scott Helme
N
News | PayPal Newsroom
AWS News Blog
AWS News Blog
D
DataBreaches.Net
Blog — PlanetScale
Blog — PlanetScale
MongoDB | Blog
MongoDB | Blog
B
Blog RSS Feed
腾讯CDC
J
Java Code Geeks
Microsoft Azure Blog
Microsoft Azure Blog
TaoSecurity Blog
TaoSecurity Blog
GbyAI
GbyAI
Y
Y Combinator Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
D
Docker

博客园 - 吾非无心

MSB4019 找不到导入的项目“C:\Users\...\AppData\Local\QtMsBuild\vs-debugtools\qt_import.props” - 吾非无心 - 博客园 类/结构最后一个成员为类(string)时可能会出现“堆损坏”(HEAP CORRUPTION DETECTED)错误 GCC在C语言中内嵌汇编 asm __volatile__ QT删除python中的单行注释 double转int QJson 存储(u)longlong有问题 QMetaObject::connectSlotsByName: No matching signal for QT数据库连接管理类 QT多重继承带来的问题及解决办法,记录备查 QT6 源码编译Win32 x86 vc++高精度计时sleep stack smashing detected 莫名其妙的错误 strdump的问题 再加一个realloc的问题 linux下简单封装读写锁 codeblocks下libacl配置 centos8 安装、配置redis6 pyftpdlib中文乱码的解决之道 CentOS8让uwsgi开机自动启动django(无需登录,无需手动) libevent学习一
QT QPixmap QImage内存泄漏
吾非无心 · 2023-09-29 · via 博客园 - 吾非无心

无论是在代码中还是在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格式的文件大小