如何将 QQuickView 的内容打印为 PDF? [英] How to print a QQuickView's contents to PDF?

查看:104
本文介绍了如何将 QQuickView 的内容打印为 PDF?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将一些 Qt(C++ 和 QML)代码从 Qt4.8 升级到 Qt5.1.

I'm upgrading some Qt (C++ & QML) code from Qt4.8 to Qt5.1.

Qt4.8 代码是一个简单的 C++QML 查看器"应用程序,继承了 QDeclarativeView 和一堆 QML.

The Qt4.8 code is a trivial C++ "QML viewer" app subclassing a QDeclarativeView, and a bunch of QML.

将其更改为使用 Qt5/QtQuick2 的 QQuickView 很容易,除了一件事:

It's been easy enough to change this to use Qt5/QtQuick2's QQuickView except for one thing:

Qt4.8 应用有一种打印到 PDF 的方法:

The Qt4.8 app has a method for printing to PDF:

void MyQMLViewer::printToPDF(const QString& filename) const {
  QPrinter printer(QPrinter::HighResolution);
  printer.setOutputFormat(QPrinter::PdfFormat);
  printer.setPageSize(QPrinter::A3);
  printer.setOutputFileName(filename);
  printer.setOrientation(QPrinter::Landscape);
  QPainter painter(&printer);
  render(&painter);
}

Qt5.1 需要进行一些环境"更改才能获得 QPrinter(即,将 QT += printsupport 添加到项目 .pro 文件和 #include <QtPrintSupport>),但似乎有一个更根本的问题,QQuickView 没有提供任何明显与 QGraphicsView 兼容的内容/QPainter/QPaintDevice QPrinter 的世界(具体来说,QQuickView 没有 render 方法,以及所有与 OpenGL 相关的绘图/绘画/渲染方法.

There were a few "environment" changes needed for Qt5.1 to get a QPrinter (ie add QT += printsupport to the project .pro file and #include <QtPrintSupport>), but there seems to be a more fundamental problem that QQuickView doesn't provide anything which is obviously compatible with the QGraphicsView/QPainter/QPaintDevice world of QPrinter (specifically, QQuickView has no render method, and all the drawing/painting/rendering-related methods it does have seem very tied up with OpenGL).

关于如何最好地从 QQuickView 获得高质量 PDF 输出的任何建议?

Any suggestions for how to best obtain high-quality PDF output from a QQuickView ?

(请注意,我不是只是想对视图进行截图;使用QDeclarativeView,上面的代码生成的 PDF 分辨率更高而不是在我最大的显示器上全屏显示的应用).

(Note that I am not simply looking to screenshot the view; with QDeclarativeView, the code above generates PDFs with much better resolution even than the app fullscreened on my largest monitor).

我看到了 将 QML 应用程序移植到 Qt 5" 指南确实提到了 QGraphicsView 特定功能的丢失,但没有提供任何解决方案(尽管它确实提到针对具有基于自定义 QPainter 的渲染的项目被购买到新制度中的情况的解决方法).

I see the "QDeclarativeItem and QDeclarativeView" section of the "Porting QML Applications to Qt 5" guide does mention the loss of QGraphicsView-specific functionality, but doesn't offer any solutions (although it does mention workrounds for the case of items with custom QPainter-based rendering being bought into the new regime).

更新,提供一些额外的背景信息:可以找到使用上述代码从 QDeclarativeView 打印的 PDF 示例 此处.在合适尺寸的显示器上有一个相同视图的 png 这里.(这实际上是一系列幻灯片中的最后一张幻灯片;它实际上是前几张幻灯片的画廊,将每张幻灯片弹到屏幕上;如果我有时间,我会研究一下画廊作为 唯一 事情并将每个分散的幻灯片转换为 Prezi 风格的演示文稿;怀疑不过,QDeclarative 的性能确实不够好,这是想要使用 QtQuick2+Qt5.2 的新场景图内容的原因之一).无论如何,如果您将 PDF 放大到 100%,您会看到文本是......好吧,我认为它比大小合理的图像文件可以管理的任何东西都要好,尽管倾斜的文本基线可能看起来有点不均匀.还有一个问题是不透明度值没有在 PDF 中表示(所以阴影和气泡"是实心的);我尝试 QtQuick2 版本的另一个动机实际上是想看看半透明元素是否得到更好的处理.我假设 PDF 只包含所有元素的光栅化(或者可能是矢量轮廓),因为像pdftotext"这样的实用程序无法从中提取任何内容.我对 PDF 工具了解不够,无法了解如何检查事物的内部结构,但我假设那里有一些层次结构,并且 QML 元素树都使用与 QML 类似的嵌套转换结构进行布局.只是为了比较和我可能正在努力的那种丰富性这里是一张海报我使用 LaTeX/Beamerposter我发现 Beamerposter 的刚性块结构相当有限(并且 繁琐) 与 QML 似乎提供的可能性相比.顺便说一句,我的愿望清单/待办事项清单上的另一件事是 可以呈现 LaTeX 源代码的 QML 元素,数学等等,只是为了两全其美.

Update with some additional background info: an example of a PDF printed from QDeclarativeView using the above code can be found here. There's a png of the same view on a decent size monitor here. (This is actually the last slide in a series of slides; it's actually a gallery of the previous slides which bounces each slide onto the screen; if I had the time I'd look into the feasibility of the gallery being the only thing and transforming each scattered slide into view for a Prezi-style presentation; suspect QDeclarative isn't really performant enough though, which is one reason for wanting to get onto QtQuick2+Qt5.2's new scene graph stuff). Anyway, If you zoom the PDF up to 100% you'll see the text is... well it's better than anything a sanely sized image file will manage I think, although the sloping text baselines perhaps look a little uneven. There is also an issue with opacity values not being represented in the PDF (so the drop shadows and "bubbles" come out solid); another one of my motivations for trying for a QtQuick2 version was actually to see if translucent elements were dealt with any better. I assume the PDF just contains rasterized (or maybe vector outlines) of all the elements as utilities like "pdftotext" can't extract anything from it. I don't know enough about PDF tools to know how to inspect the internal structure of the thing but I assume there's some hierarchy there and the QML element tree is all laid out using a similar structure of nested transforms to the QML. Just for comparison and the sort of richness I'm potentially working towards here's a poster I did with LaTeX/Beamerposter; I find Beamerposter's rigid block structure rather limiting (and fiddly) compared with the possibilities QML seems to offer though. BTW, another thing on my wishlist/todolist is a QML element which can render LaTeX source, math and all, just to get the best of both worlds.

更新:最近的Qt 博客文章 关于 Qt5.8 中所有后端更改的评论链接到 这个 Qt 问题 使用 QPainter 渲染的 QtQuick 场景的新可能性来渲染 PDF.

Update: Recent Qt blog post on all the backend changes in Qt5.8 has a comment linking to this Qt issue to use the new possibility of QPainter-rendered QtQuick scenes to render PDFs.

推荐答案

目前,Qt 中没有支持将场景图渲染为 pdf 的代码.用于渲染 Qt Quick 2 的基础数据保存在场景图中.正如 Laszlo 所建议的,您需要迭代场景图并生成 PDF 基元.那里有一些阻抗不匹配,但它应该可以通过一些汗水来实现.我认为概念证明可能足够小以适应这里,所以我会看到它是多么容易:)

At the moment, there is no code in Qt that supports rendering of a scene graph to a pdf. The underlying data that is used to render Qt Quick 2 is held in the scene graph. As Laszlo suggests, you'd need to iterate the scene graph and generate PDF primitives. There's some impedance mismatch there, but it should be doable with some sweat. I think a proof of concept could be small enough to fit here, so I'll see how easy it could be :)

如果您真的想要 PDF,您目前别无选择,只能将其渲染为 300dpi 的大图像并将其包装在 PDF 中.如果海报有大面积的纯色,则图像不必很大.PDF可以做TIFF编码,也可以做JPEG编码.

If you really want a PDF, you currently have no choice but to render it to a large image at 300dpi and wrap that in a PDF. The image doesn't have to be large if the poster has large areas of solid color. PDF can do do TIFF encoding and also JPEG encoding.

这篇关于如何将 QQuickView 的内容打印为 PDF?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆