Qt 使用QPrinter打印到PDF时QPaint崩溃

Qt 使用QPrinter打印到PDF时QPaint崩溃,qt,qpainter,qprinter,Qt,Qpainter,Qprinter,我使用QPrinter和QPainter类在Windows虚拟设备上打印成PDF文件。QPaint对象打开一个对话框窗口,可以在其中介绍PDF文件的路径和名称 对于预期用途,它工作正常。但是,当按下对话框中的“取消”按钮时,应用程序崩溃。以下是复制错误的代码段: #include <iostream> #include <QApplication> #include <QPrinterInfo> #include <QPainter> int m

我使用QPrinter和QPainter类在Windows虚拟设备上打印成PDF文件。QPaint对象打开一个对话框窗口,可以在其中介绍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;
}
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
QApplication应用程序(argc、argv);
foreach(QPrinterInfo printerInfo,QPrinterInfo::AvailablePrants()){
if(printerInfo.state()==QPrinter::PrinterState::Error)
继续;
//查找生成pdf的虚拟打印机设备。
if(printerInfo.printerName()=“Microsoft打印到PDF”)
{
QPrinter*QPrinter=新的QPrinter(printerInfo,QPrinter::高分辨率);
QPainter*QPainter=新的QPainter();
//此语句将弹出一个文件选择对话框。
//当它被取消时,应用程序崩溃。。。
qPainter->begin(qPrinter);
//…而这句话永远也达不到。
std::cout newPage();
qPainter->drawText(100100,“Mauris ut urna eget dui eleifend placerat”);
qPrinter->newPage();
//关闭打印机并进行清理。
qPainter->end();
删除qPrinter;
删除qPainter;
}
}
返回0;
}
通过按Cancel按钮,应用程序在调用QPaint::begin()期间崩溃。我错过什么了吗?这种方法会有缺陷吗

更新:使用try-catch保护对QPaint::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;
}
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
QApplication应用程序(argc、argv);
foreach(QPrinterInfo printerInfo,QPrinterInfo::AvailablePrants()){
if(printerInfo.state()==QPrinter::PrinterState::Error)
继续;
//查找生成pdf的虚拟打印机设备。
if(printerInfo.printerName()=“Microsoft打印到PDF”)
{
QPrinter*QPrinter=新的QPrinter(printerInfo,QPrinter::高分辨率);
QPainter*QPainter=新的QPainter();
//此语句将弹出一个文件选择对话框。
//当它被取消时,应用程序崩溃。。。
尝试
{
qPainter->begin(qPrinter);
}
捕获(…){}
//…而这句话永远也达不到。
std::cout drawText(100100,“Lorem ipsum door sit amet,Concetetur Adipising Elite.”);
qPrinter->newPage();
qPainter->drawText(100100,“Mauris ut urna eget dui eleifend placerat”);
qPrinter->newPage();
qPainter->end();
}
//关闭打印机并进行清理。
删除qPrinter;
删除qPainter;
}
}
返回0;
}

尝试使用
QPrinter::screensolution
代替
QPrinter::HighResolution

PDF打印机会导致500 MB的内存分配,这对于32位Qt来说太多了,崩溃发生在QImage的malloc中


或者,您可以切换到64位Qt。它仍然很慢,但打印很好。如果您想要比
screensolution
更高的dpi,可以使用
QPrinter::setResolution(int-dpi)
将其设置为300左右。

尝试使用
QPrinter::screensolution
代替
QPrinter::HighResolution

PDF打印机会导致500 MB的内存分配,这对于32位Qt来说太多了,崩溃发生在QImage的malloc中


或者,您可以切换到64位Qt。它仍然很慢,但打印很好。如果您希望dpi高于
屏幕分辨率
,可以使用
QPrinter::setResolution(int dpi)
将其设置为300左右。

QPaint::begin()
返回
bool
,只有当它返回
true
时才应继续。检查它是否返回
false
按“取消”时,我没有测试自己,但我强烈怀疑是这样。这似乎就是这个错误,您需要添加try-catch-around-beginmethod@KarstenKoop崩溃发生在begin()完成之前。@demonplus谢谢,看来这一定是问题所在。注意。应用程序提供给您的任何崩溃详细信息?
QPainter::begin()
返回
bool
,只有当它返回
true
时,您才应该继续。检查它是否返回
false
按“取消”时,我没有测试自己,但我强烈怀疑是这样。这似乎就是这个错误,您需要添加try-catch-around-beginmethod@KarstenKoop崩溃发生在begin()完成之前。@demonplus谢谢,看来这一定是问题所在。尊敬的。应用程序向您提供了崩溃的详细信息吗?