1

我正在使用类QPrinterQPainter使用 Windows 虚拟设备打印成 PDF 文件。QPainter对象打开一个对话窗口,可以在其中介绍 PDF 文件的路径和名称。

它适用于预期用途。但是,当按下对话框中的取消按钮时,应用程序崩溃。这是一个复制错误的代码片段:

#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;
}

通过按下取消按钮,应用程序在调用QPainter::begin()期间崩溃。我错过了什么吗?该方法可能存在错误吗?

更新:使用 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;
}
4

1 回答 1

0

尝试QPrinter::ScreenResolution改用QPrinter::HighResolution.

PDF 打印机设置 1200 dpi,这导致 500 MB 内存分配,这对于 32 位 Qt 来说太多了,然后崩溃是来自 QImage 的 malloc。

或者,您可以切换到 64 位 Qt。它仍然会很慢,但打印效果很好。如果您想要比 更高的 dpi ScreenResolution,可以将其设置QPrinter::setResolution(int dpi)为 300 之类的值。

于 2018-01-13T15:36:37.027 回答