简体   繁体   中英

QPainter crashes when printing to PDF with QPrinter

I am using the classes QPrinter and QPainter to print into PDF files with a Windows virtual device. The QPainter object opens a dialog window where one could introduce the path and name of the PDF file.

It works correctly for the intented use. However, when pressing the Cancel button in the dialog, the application crashes. Here is a code snippet that replicates the error:

#include <iostream>
#include <QApplication>
#include <QPrinterInfo>
#include <QPainter>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    foreach(QPrinterInfo printerInfo, QPrinterInfo::availablePrinters()) {
        if (printerInfo.state() == QPrinter::PrinterState::Error)
            continue;

        // Look for the virtual printer device that generates a pdf.
        if (printerInfo.printerName() == "Microsoft Print to PDF")
        {
            QPrinter * qPrinter = new QPrinter(printerInfo, QPrinter::HighResolution);
            QPainter * qPainter = new QPainter();

            // This statement pops up a file selection dialog.
            // When it is cancelled, the application crashes ...
            qPainter->begin(qPrinter);

            // ... and this statement is never reached.
            std::cout << "Starting printing on the pdf file." << std::endl;

            // We print some text in the PDF file.
            qPainter->drawText(100, 100, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
            qPrinter->newPage();
            qPainter->drawText(100, 100, "Mauris ut urna eget dui eleifend placerat.");
            qPrinter->newPage();

            // Close the printer and clean-up.
            qPainter->end();
            delete qPrinter;
            delete qPainter;
        }
    }

    return 0;
}

By pressing the Cancel button the application crashes during the call to QPainter::begin() . Am I missing something? Could there be a bug in that method?

Update: protecting the call to QPainter::begin() with a try-catch did not prevent the crash:

#include <iostream>
#include <QApplication>
#include <QPrinterInfo>
#include <QPainter>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    foreach(QPrinterInfo printerInfo, QPrinterInfo::availablePrinters()) {
        if (printerInfo.state() == QPrinter::PrinterState::Error)
            continue;

        // Look for the virtual printer device that generates a pdf.
        if (printerInfo.printerName() == "Microsoft Print to PDF")
        {
            QPrinter * qPrinter = new QPrinter(printerInfo, QPrinter::HighResolution);
            QPainter * qPainter = new QPainter();

            // This statement pops up a file selection dialog.
            // When it is cancelled, the application crashes ...
            try
            {
                qPainter->begin(qPrinter);
            }
            catch(...) { }

            // ... and this statement is never reached.
            std::cout << "Starting printing on the pdf file." << std::endl;

            if (qPainter->isActive())
            {
                // We print some text in the PDF file.
                qPainter->drawText(100, 100, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
                qPrinter->newPage();
                qPainter->drawText(100, 100, "Mauris ut urna eget dui eleifend placerat.");
                qPrinter->newPage();
                qPainter->end();
            }

            // Close the printer and clean-up.
            delete qPrinter;
            delete qPainter;
        }
    }

    return 0;
}

Try using QPrinter::ScreenResolution instead QPrinter::HighResolution .

The PDF printer sets 1200 dpi , which results in a 500 MB memory allocation, which is too much with 32 Bit Qt, the crash is then in malloc from QImage.

Alternatively you can switch to 64 Bit Qt. It will still be slow, but print fine. If you want a higher dpi than ScreenResolution , you can set it with QPrinter::setResolution(int dpi) to something like 300.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM