我需要知道如何将一个QWidget打印成PDF文件。这个Widget(QDialog)包含很多标签,一些QPlainTextEdit和一个背景图片。该对话框显示了一个已填写所有字段的收据。
我已经尝试使用QTextDocument和html来实现此目的,但是收据的复杂性(大量图像和格式自定义)使得html输出完全混乱。
这是文档。
收据图片
我需要知道如何将一个QWidget打印成PDF文件。这个Widget(QDialog)包含很多标签,一些QPlainTextEdit和一个背景图片。该对话框显示了一个已填写所有字段的收据。
我已经尝试使用QTextDocument和html来实现此目的,但是收据的复杂性(大量图像和格式自定义)使得html输出完全混乱。
这是文档。
收据图片
您需要使用 QPrinter
,这是必须使用的对象,需要 QPainter
在 QPrinter
中绘制小部件。
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QDialog w;
w.setLayout(new QVBoxLayout());
w.layout()->addWidget(new QLineEdit("text"));
w.layout()->addWidget(new QPushButton("btn"));
w.layout()->addWidget(new QPlainTextEdit("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris rutrum magna semper nisi faucibus, at auctor dolor ullamcorper. Phasellus facilisis blandit augue sit amet placerat. Aliquam nec imperdiet diam. Proin dignissim vulputate metus, nec tincidunt magna vulputate ac. Praesent vel felis ac dolor viverra tempus eu vitae neque. Nulla efficitur gravida arcu id suscipit. Maecenas placerat egestas velit quis interdum. Nulla diam massa, hendrerit vitae mi et, placerat aliquam nisl. Donec tincidunt lobortis orci, quis egestas augue tempus sed. Nulla vel dolor eget ipsum accumsan placerat ut at magna."));
w.show();
QPushButton btn("print");
btn.show();
QObject::connect(&btn, &QPushButton::clicked, [&w](){
QPrinter printer(QPrinter::HighResolution);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName("output.pdf");
printer.setPageMargins(12, 16, 12, 20, QPrinter::Millimeter);
printer.setFullPage(false);
QPainter painter(&printer);
double xscale = printer.pageRect().width() / double(w.width());
double yscale = printer.pageRect().height() / double(w.height());
double scale = qMin(xscale, yscale);
painter.translate(printer.paperRect().center());
painter.scale(scale, scale);
painter.translate(-w.width()/ 2, -w.height()/ 2);
w.render(&painter);
});
return a.exec();
}
Widget:
output.pdf
pageRect()
和paperRect()
函数上收到了警告。这些函数似乎已经过时。
以下是去除了废弃函数的代码的前后对比。//-------------------------- Code BEFORE --------------------------//
double xscale = printer.pageRect().width() / double(w.width());
double yscale = printer.pageRect().height() / double(w.height());
double scale = qMin(xscale, yscale);
painter.translate(printer.paperRect().center());
painter.scale(scale, scale);
painter.translate(-w.width()/ 2, -w.height()/ 2);
w.render(&painter);
//-----------------------------------------------------------------//
//-------------------------- Code AFTER ---------------------------//
double pageRectWidth = printer.pageLayout().pageSize().sizePixels(96).width()-printer.pageLayout().marginsPixels(96).left()-printer.pageLayout().marginsPixels(96).right();
double pageRectHeight = printer.pageLayout().pageSize().sizePixels(96).height()-printer.pageLayout().marginsPixels(96).top()-printer.pageLayout().marginsPixels(96).bottom();
double xscale = pageRectWidth / double(w.width());
double yscale = pageRectHeight / double(w.height());
double scale = qMin(xscale, yscale);
painter.translate(QPoint(printer.pageLayout().pageSize().sizePixels(96).width()/2,printer.pageLayout().pageSize().sizePixels(96).height()/2));
painter.scale(scale, scale);
painter.translate(-w.width()/ 2, -w.height()/ 2);
w.render(&painter);
//-----------------------------------------------------------------//
我在sizePixels()
函数中使用了96,因为这是默认分辨率。
希望这段代码能够帮到你 :)