无法生成具有可接受输出质量的PDF我试图在Windows下使用Qt5生成pdf。我的文档包含文本,图像和图表。由于我熟悉Qt和Qwt,我相信最好的策略是创建一个带有我的文档布局的QWidget
,并将其打印出来。但是我面临的问题并不能以可接受的结果结束。使用Qt
这是我的MCVE,用一个简单的页的文件:
- 基于Qt document并用标题和图像
- 一块文本
- 的简单图表
的报头How can I print a QWidget in Qt?,我结束了这段代码:
main.cpp中:
#include <QApplication>
#include <QIcon>
#include <QDesktopServices>
#include <QWidget>
#include <QPrinter>
#include <QPainter>
#include <QPagedPaintDevice>
#include <QUrl>
#include "ui_report.h"
#include "qwt_plot.h"
#include "qwt_plot_curve.h"
#include "qwt_plot_canvas.h"
#include "qwt_point_data.h"
#include "qwt_legend.h"
#include <sstream>
#include <memory>
bool printWidget(QWidget& widget, bool highResolution, const std::string& fileName)
{
QPrinter printer(highResolution ? QPrinter::HighResolution : QPrinter::ScreenResolution);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOrientation(QPrinter::Portrait);
printer.setPaperSize(QPrinter::A4);
printer.setPageMargins(15,15,15,15,QPrinter::Millimeter);
printer.setFullPage(true);
printer.setOutputFileName(fromSDEString(fileName.c_str()));
QPainter painter(&printer);
double xscale = printer.pageRect().width()/double(widget.width());
double yscale = printer.pageRect().height()/double(widget.height());
double scale = qMin(xscale, yscale);
painter.translate(printer.paperRect().x() + printer.pageRect().width()/2,
printer.paperRect().y() + printer.pageRect().height()/2);
painter.scale(scale, scale);
painter.translate(-widget.width()/2, -widget.height()/2);
widget.render(&painter, QPoint(), QRegion(), QWidget::DrawChildren);
return painter.end();
}
bool generateReport(bool drawWithPrinterResolution, bool printHighResolution, const std::string& fileName)
{
QWidget widget;
Ui::Report ui;
ui.setupUi(&widget);
if (drawWithPrinterResolution)
{
QPrinter printer(printHighResolution ? QPrinter::HighResolution : QPrinter::ScreenResolution);
printer.setOrientation(QPrinter::Portrait);
printer.setPaperSize(QPrinter::A4);
printer.setPageMargins(15,15,15,15,QPrinter::Millimeter);
printer.setFullPage(true);
// force printer page size to be used:
QSize pageSize = printer.pageRect().size();
widget.resize(pageSize);
}
ui.header->setFrameShape(QFrame::Shape::Box);
QHBoxLayout* headerLayout = new QHBoxLayout(ui.header);
QLabel* icon = new QLabel(ui.header);
QSize size = ui.header->size();
icon->setPixmap(QPixmap(":/gui_test/mainframe.png").scaledToHeight(size.height()));
headerLayout->addWidget(icon);
headerLayout->addWidget(new QLabel("Document title",ui.header));
headerLayout->setStretch(0, 0);
headerLayout->setStretch(1, 1);
ui.inputs->setText("<b>Info</b>: Information");
QwtPlot* plot = new QwtPlot(&widget);
QwtPlotCurve* curve = new QwtPlotCurve("Plots");
curve->setStyle(QwtPlotCurve::Lines);
QVector<QPointF> samples;
for (size_t i = 0; i != 100; ++i)
{
samples.push_back(QPointF(i,20*i+10));
}
curve->setData(new QwtPointSeriesData(samples));
curve->attach(plot);
plot->setTitle("Result");
plot->setAxisScale(QwtPlot::xBottom, samples.front().rx(), samples.back().rx());
plot->replot();
ui.graphLayout->addWidget(plot);
if (printWidget(widget, printHighResolution, fileName))
{
QDesktopServices::openUrl(QUrl::fromLocalFile(fileName.c_str()));
return true;
}
else
{
return false;
}
}
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
app.setWindowIcon(QIcon(":/gui_test/mainframe.png"));
generateReport(false, false, "report_small_widget_to_screen.pdf");
generateReport(false, true, "report_small_widget_to_high.pdf");
generateReport(true, false, "report_big_widget_to_screen.pdf");
generateReport(true, true, "report_big_widget_to_high.pdf");
return 0;
}
report.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Report</class>
<widget class="QWidget" name="Report">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>525</width>
<height>742</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0,100,0">
<item>
<widget class="QFrame" name="header"/>
</item>
<item>
<widget class="QLabel" name="inputs">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="graphLayout"/>
</item>
<item>
<widget class="QWidget" name="footer" native="true"/>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
mainframe.png:的256×256像素A Qt的图标:http://icons.iconarchive.com/icons/alecive/flatwoken/256/Apps-Qt-icon.png。
正如你可以看到,这会产生4个文件:
- report_small_widget_to_screen.pdf:其中插件与来自UI文件(252x742)小A4比创建,然后印有
QPrinter::ScreenResolution
- report_small_widget_to_high.pdf :在哪里插件与来自UI文件(252x742)小A4比创建,然后印有
QPrinter::HighResolution
- report_big_widget_to_screen.pdf:其中插件被缩放到打印机的页大小(793x1123),然后印有
QPrinter::ScreenResolution
- report_big_widget_to_high.pdf:当小部件扩展到打印机的页面大小(9917x14033),然后印有
QPrinter::HighResolution
没有给我一个可以接受的结果:
- report_small_widget_to_screen.pdf:文本,Qt的图标QWT图是像素化
- report_small_widget_to_high.pdf:文字是确定的,但Qt的图标和QWT图是像素化
- report_big_widget_to_screen.pdf:文本,Qt的图标和QWT图是像素化
- report_big_widget_to_high.pdf:文本,Qt图标和Qwt图表非常小,几乎不可读。但现在Qwt的情节不再像素化了
我应该改变什么来获得一个不错的输出?
- 使用高分辨率(非像素化)绘制的文本与report_small_widget_to_high中一样。PDF
- 随着图标具有高分辨率(未像素化)正在制定
- 随着图被描绘具有高分辨率(未像素化)
report_small_widget_to_screen.pdf样子(一切都是像素化) :
report_small_widget_to_high.pdf外观像(只有文字没有像素化):
report_big_widget_to_high.pdf样子(一切都太小):
注:我只是跑相同的测试与更大的.ui资源(2100x2970),然后图像分辨率看起来更好,但文字显示非常小。我想知道QWidget打印在这里是合适的解决方案,因为它看起来像文本大小取决于用户界面大小,所以你无法控制文本的大小(就像你在像Word这样的文档中使用字体大小......) )
什么分辨率是您图标? – eyllanesc
@eyllanesc:256x256像素 – jpo38
您可以通过github或类似的工具共享您的项目,以节省时间。 – eyllanesc