PDA

View Full Version : Memory Leak with QPrinter/QPainter



cevou
31st May 2010, 09:47
Hi,

if I print a lot of QImages using QPrinter (with preview in QPrintPreviewDialog) the memory usage of my program increases a lot and after finishing printing the memory still isn't released.

Example:


QPrinter *printer = new Printer();
...
...
...
QPainter painter;
painter.begin(printer);
QImage image;
image.load(...);
painter.drawImage(...,image);
painter.end();

high_flyer
31st May 2010, 10:07
is the snippet of code you posted in a loop?
Can you post the code "frame" of this code? (relevant before and after lines.)

Lykurg
31st May 2010, 10:50
a) where do you delete the printer?
b) what tool are you using to measure the memory usage? Because it is like that the memory is freed, but still reserved for the application.

cevou
31st May 2010, 11:19
I'm using the activity monitor in Mac OSX (I think this is the equivalent to task manager in Windows)

Here some more Code to understand the situation better:

Constructor of my print object


Drucken::Drucken() : QObject() {
printer = new QPrinter(QPrinter::HighResolution);
printer->setPageMargins(5.0,5.0,5.0,5.0,QPrinter::Millimete r);
printer->setOrientation(orientation);
if (outputType == 0) {
printer->setOutputFormat(QPrinter::NativeFormat);
} else {
printer->setOutputFormat(QPrinter::PdfFormat);
}
dialog = new QPrintPreviewDialog(printer);
dialog->setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint);
dialog->setWindowTitle("TurnFix - Drucken");
dialog->setWindowIcon(QIcon(":/icons/icon.png"));
dialog->printer()->setPaperSize(paperSize);
connect(dialog, SIGNAL(paintRequested(QPrinter*)), this, SLOT(print(QPrinter*)));
}


print method


void Drucken::print(QPrinter *prt) {
curr_printer = prt;
if (outputType == 2) curr_printer->setOutputFileName(outputFileName);
pr = curr_printer->pageRect();
painter.begin(curr_printer);

// This is painted on every page
QSqlQuery layoutData;
layoutData.prepare(...);
layoutData.bindValue(0,...);
layoutData.exec();

while (layoutData.next()) {
if (!customImages.contains(layoutData.value(6).toStri ng())) {
QImage pm;
pm.load(layoutData.value(6).toString());
if (!pm.isNull()) {
customImages.insert(layoutData.value(6).toString() ,pm.scaled(mmToPixel(layoutData.value(4).toDouble( )),mmToPixel(layoutData.value(5).toDouble()),Qt::K eepAspectRatio,Qt::SmoothTransformation));
}
pm.~QImage();
}
painter.drawImage(mmToPixel(layoutData.value(2).to Double()),mmToPixel(layoutData.value(3).toDouble() ),customImages.value(layoutData.value(6).toString( )));
}
// End of code for every page

...

painter.end();
customImages.clear();

}

high_flyer
31st May 2010, 11:46
You didn't answer Lykurgs question, where you delete the printer pointer?
You don't have to call pm.~QImage(); (line 20 second code block) since it will be called automatically at the end of the if() block.
Also, what type of a container is 'customImages'?

cevou
31st May 2010, 12:00
I don't delete the printer pointer at the moment. I tried to delete it after painter.end() but that caused my program to crash.
customImages is a QMap<QString,QImage>. I'm using that container to "store" the images because they are printed on every page.

high_flyer
31st May 2010, 12:17
don't delete the printer pointer at the moment.
Well, that is one memory leak you have.
Just parent your printer object, it will be destroyed when its parent is destroyed.
See if this fixes the problem, if not, then make sure you are deleting or parenting all heap allocated QOjects.
Objects that you allocate on the heap and are not QObjects you have to delete your self.

Lykurg
31st May 2010, 14:12
I don't delete the printer pointer at the moment.
... and then you wonder about memory leaks :D :D
parent it as high_flyer had suggested or simple delete them in the destructor of your Drucken class.

cevou
31st May 2010, 14:19
Ok, it releases the memory now after printing or closing the QPrintPreviewDialog.
However, while printing the memory usage still increases a lot (from 32MB to something like 600-700MB). Is that because of the pictures?

tbscope
31st May 2010, 14:24
I'm not sure how many pictures you have, but this

customImages.insert(...);
while you're printing will get pretty big pretty soon :-)
700 images of 1MB = 700MB

Why do you keep a list of images and clear it at the end?
Isn't there another way without keeping all those pictures in memory?

cevou
31st May 2010, 14:31
Usually there are only up to 5 pictures. These pictures are on every page and there can be over 100 pages. That's why I thought putting the pictures in a QMap would save memory.

cevou
1st June 2010, 07:24
I tried using QPixmap instead of QImage now and it seems that it doesn't use so much memory anymore.