下面这个简单的方法,就会导致内存泄漏,不信你可以自己试试。
void copyImageToClipboard(){
QImage image(1200, 800, QImage::Format_RGB32);
image.fill(Qt::red);
QClipboard *clipboard = QApplication::clipboard();
clipboard->setImage(image);
}
要想解决这个问题,只有放弃使用QClipboard,转而使用系统API,才会彻底解决内存泄漏的问题。
如下代码所示:
void Util::saveImgToClipboard(const QImage& img)
{
auto width = img.width();
auto height = img.height();
HDC screenDC = GetDC(nullptr);
HDC memoryDC = CreateCompatibleDC(screenDC);
HBITMAP hBitmap = CreateCompatibleBitmap(screenDC, width, height);
DeleteObject(SelectObject(memoryDC, hBitmap));
BITMAPINFO bitmapInfo = { 0 };
bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmapInfo.bmiHeader.biWidth = width;
bitmapInfo.bmiHeader.biHeight = -height;
bitmapInfo.bmiHeader.biPlanes = 1;
bitmapInfo.bmiHeader.biBitCount = 32;
SetDIBitsToDevice(memoryDC, 0, 0, width, height, 0, 0, 0, height, img.bits(), &bitmapInfo, DIB_RGB_COLORS);
if (!OpenClipboard(nullptr)) {
QMessageBox::warning(nullptr, "Error", "Failed to open clipboard when save to clipboard.", QMessageBox::StandardButton::Ok);
return;
}
EmptyClipboard();
SetClipboardData(CF_BITMAP, hBitmap);
CloseClipboard();
ReleaseDC(nullptr, screenDC);
DeleteDC(memoryDC);
DeleteObject(hBitmap);
}
我估计,系统API提供了CloseClipboard,Qt没有这个关闭剪切板的API,这是导致内存泄漏的根本原因。