無法生成具有可接受輸出質量的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