使用Qt

weixin_38082682 2019-09-12 03:34:58

无法生成具有可接受输出质量的PDF我试图在Windows下使用Qt5生成pdf。我的文档包含文本,图像和图表。由于我熟悉Qt和Qwt,我相信最好的策略是创建一个带有我的文档布局的QWidget,并将其打印出来。但是我面临的问题并不能以可接受的结果结束。 这是我的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这样的文档中使用字体大小......) )








...全文
48 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_38084861 2019-09-12
  • 打赏
  • 举报
回复

就我个人而言,我会强烈建议将内容创建为QTextDocument,然后将其打印出来。你可以(IIRC,有一段时间没有使用QwtPlot)将图表渲染成图像。然后很容易add the image到任何你想要的文件。当然,和你的静态图像一样。您可以在文档中使用HTML/CSS(尽管类名称中包含“文本”)以及许多其他选项。 实例添加要求: 这将是非常简单的,并没有完全形成,但希望它可以帮助... QTextDocument qtdoc; // start with a QTextDocument // prepare standard html with embedded image QString html = "<html><body>" \ "<h1>Hello World!</h1>" \ "<img src='mydata://myimg.png' border='0' />" \ "</body></html>"; QImage image = getChartImage(); // theoretical function // here we add the actual image data to the document qtdoc.addResource(QTextDocument::ImageResource, QUrl("mydata://myimg.png"), image); qtdoc.setHtml(html); // document is now fully formed and ready for display/print 打印到PDF或HTML文件: void printToFile(const QTextDocument & qtdoc) { QString fn = QFileDialog::getSaveFileName(this, tr("Select output file"), QString(), tr("PDF Files(*.pdf);;HTML-Files (*.htm *.html)")); if (fn.isEmpty()) return; if (fn.endsWith(".pdf", Qt::CaseInsensitive)) { QPrinter printer; printer.setPageMargins(10.0,10.0,10.0,10.0,printer.Millimeter); printer.setOutputFormat(QPrinter::PdfFormat); printer.setColorMode(QPrinter::Color); printer.setOutputFileName(fn); qtdoc.print(&printer); } else { // HTML QTextDocumentWriter writer(fn); writer.write(qtdoc); } } 输出到打印机: void print(const QTextDocument & qtdoc) { QPrinter printer; printer.setPageMargins(10.0,10.0,10.0,10.0,printer.Millimeter); QPrintDialog *dialog = new QPrintDialog(&printer, this); dialog->setWindowTitle(tr("Print Document")); if (dialog->exec() != QDialog::Accepted) return; qtdoc.print(&printer); } 的工作版本的实际截图(它的代码开始here,但有点烦琐的遵循): 和PDF导出:http://max.wdg.us/docs/so/SO-47879329.pdf

433

社区成员

发帖
与我相关
我的任务
社区描述
其他技术讨论专区
其他 技术论坛(原bbs)
社区管理员
  • 其他技术讨论专区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧