简体   繁体   English

使用QPrinter打印到PDF时QPainter崩溃

[英]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. 我使用QPrinterQPainter类打印到带有Windows虚拟设备的PDF文件。 The QPainter object opens a dialog window where one could introduce the path and name of the PDF file. QPainter对象打开一个对话窗口,可以在其中引入PDF文件的路径和名称。

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() . 通过按“ 取消”按钮,应用程序在调用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: 更新:使用try-catch保护对QPainter :: begin()的调用并不能防止崩溃:

#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 . 尝试使用QPrinter::ScreenResolution代替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. PDF打印机设置1200 dpi ,这导致500 MB内存分配,32位Qt太多,然后崩溃来自QImage的malloc。

Alternatively you can switch to 64 Bit Qt. 或者,您可以切换到64位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. 如果你想要比ScreenResolution更高的dpi,你可以使用QPrinter::setResolution(int dpi)将其设置为300。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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