Qt 打印支持
Qt 打印支持模块为打印提供了广泛的跨平台支持。利用每个平台的打印系统,Qt 应用程序可以打印到连接的打印机,以及通过网络远程打印机。打印系统还支持 PDF 文件生成,为基本报告生成功能提供了基础。
Qt 打印支持在 iOS 上不可用。
支持打印的类
以下类支持选择和设置打印机以及打印输出。
用于配置打印机的打印对话框的基类实现 | |
表示一系列页面范围的集合 | |
打印机页面相关选项的配置对话框 | |
指定打印机配置的对话框 | |
定义了 QPrinter 与指定的打印子系统交互的接口 | |
用于预览和配置打印机输出的页面布局的对话框 | |
用于预览打印机输出的页面布局的部件 | |
在打印机上绘制画面的绘制设备 | |
提供了访问现有打印机信息的方法 |
绘制设备和打印
打印机由 QPrinter 表示,这是一个特殊的绘制设备,它提供了打印功能,如支持多页和双面输出。因此,打印涉及到使用 QPainter 将内容绘制到一系列页面上,就像在自定义部件或图像上绘制一样。
创建 QPrinter
虽然可以在不要求用户输入的情况下构造和配置 QPrinter 对象,但打印通常是在用户请求后执行,例如,当用户在 GUI 应用程序中选择 文件|打印... 菜单项时。在这种情况下,一个新构造的 QPrinter 对象被提供给 QPrintDialog,允许用户指定要使用的打印机、纸张大小和其他打印属性。
QPrinter printer; QPrintDialog dialog(&printer, this); dialog.setWindowTitle(tr("Print Document")); if (editor->textCursor().hasSelection()) dialog.addEnabledOption(QAbstractPrintDialog::PrintSelection); if (dialog.exec() != QDialog::Accepted) return;
还可以通过在将其提供给打印对话框之前修改 QPrinter 来设置某些默认属性。例如,为打印大量报告而生成批次的程序可能将 QPrinter 设置为默认写入本地文件而不是打印机。
在页面上绘制
一旦构造并设置了 QPrinter 对象,就可以使用它进行绘制操作。我们可以这样构建和设置画家
QPrinter printer(QPrinter::HighResolution); printer.setOutputFileName("print.ps"); QPainter painter; painter.begin(&printer); for (int page = 0; page < numberOfPages; ++page) { // Use the painter to draw on the page. if (page != lastPage) printer.newPage(); } painter.end();
由于 QPrinter 从空白页开始,我们只需要在绘制每一页之后调用 newPage() 函数,除非是最后一页。
当我们调用 end() 时,文档会被发送到打印机,或者写入本地文件。
坐标系
QPrinter 提供了可以用来获取纸张尺寸(纸张矩形)和可打印区域尺寸(页面矩形)信息的功能。这些尺寸以逻辑设备坐标给出,可能不同于设备本身使用的物理坐标,这表明打印机可以以(通常更高的)比用户显示的分辨率更高的分辨率渲染文本和图形。
尽管我们不需要自己处理逻辑坐标和物理坐标之间的转换,但我们仍然需要将对绘画操作应用转换,因为用于屏幕绘制的像素测量值对于典型打印机的更高分辨率来说通常太小。
打印机和画家坐标系 paperRect() 和 pageRect() 函数提供了关于打印使用的纸张尺寸以及可以绘制在纸张上的区域大小的信息。 pageRect() 返回的矩形通常位于 paperRect() 返回的矩形之内。使用以 QPrinter 作为底层绘图设备的 QPainter 绘图时,您不需要考虑这些区域的位置和尺寸;画家坐标系的起点将与页面矩形的左上角重合,绘画操作将被裁剪到页面的可绘制部分边界内。 |
绘图系统在绘制文本时会自动使用正确的设备度量,但是,如果您需要使用从字体度量信息得到的信息来定位文本,您需要确保在构造 QFontMetrics 和 QFontMetricsF 对象时指定打印设备,或者确保每个使用的 QFont 都使用接受一个 QPaintDevice 参数的构造函数来构建。
打印小部件
要打印一个部件,您可以使用 QWidget::render() 函数。如上所述,打印机的分辨率通常高于屏幕分辨率,因此您可能需要缩放画家。您还可能想要将部件定位在页面上的某个位置。以下代码示例展示了这可能是什么样子。
QPainter painter; painter.begin(&printer); const auto pageLayout = printer.pageLayout(); const auto pageRect = pageLayout.paintRectPixels(printer.resolution()); const auto paperRect = pageLayout.fullRectPixels(printer.resolution()); double xscale = pageRect.width() / double(myWidget->width()); double yscale = pageRect.height() / double(myWidget->height()); double scale = qMin(xscale, yscale); painter.translate(pageRect.x() + paperRect.width() / 2., pageRect.y() + paperRect.height() / 2.); painter.scale(scale, scale); painter.translate(-myWidget->width() / 2., -myWidget->height() / 2.); myWidget->render(&painter);
这将使部件在页面上居中,并将其缩放以适应页面。
从复杂组件打印
某些小部件,如 QTextEdit 和 QGraphicsView,显示通常由其他类的实例管理的丰富内容,如 QTextDocument 和 QGraphicsScene。因此,通常是这些内容处理类提供了打印功能,要么通过一个可以执行完整任务的函数,要么通过一个接受一个现有的 QPainter 对象的函数,或者一些小部件提供了便利函数来公开底层的打印功能,避免仅仅为了调用单个函数就需要获取内容处理程序。
以下表格显示了哪些类和函数负责从选定的小部件中打印。对于不直接公开打印功能的小部件,可以通过相应小部件API中的一个函数获得包含此功能的内容处理类。
小部件 | 打印函数 | 接受 |
---|---|---|
QGraphicsView | QGraphicsView::render() | QPainter |
QSvgWidget | QSvgRenderer::render() | QPainter |
QTextEdit | QTextDocument::print() | QPrinter |
QTextLayout | QTextLayout::draw() | QPainter |
QTextLine | QTextLine::draw() | QPainter |
QTextEdit 需要一个 QPrinter 而不是 QPainter,因为它使用了配置的页面尺寸信息来在打印文档中插入合适的分页。
使用模块
使用 Qt 模块需要对模块库进行链接,无论是直接还是通过其他依赖项。许多构建工具都为此提供了专用支持,包括 CMake 和 qmake。
使用 CMake 构建
使用 find_package()
命令在 Qt6
软件包中定位所需的模块组件
find_package(Qt6 REQUIRED COMPONENTS PrintSupport) target_link_libraries(mytarget PRIVATE Qt6::PrintSupport)
另请参阅 使用 CMake 构建 概述。
使用 qmake 构建
要使用 qmake 构建配置模块,请在项目的 .pro 文件中将模块添加为 QT
变量的值
QT += printsupport
模块演化
Qt 打印支持更改 列出了 Qt 6 系列Qt 中模块 API 和功能的重要更改。
许可证和商标
Qt 打印支持模块可在 Qt 公司 的商业许可证下使用。此外,它还可在免费软件许可证下使用: GNU Lesser General Public License,版本 3,或 GNU General Public License,版本 2。有关详细信息,请参阅 Qt 许可证。
请注意,Adobe®对其商标(包括徽标)的使用有限制,包括与 PDF 一起使用;例如,“Adobe PDF”。请参阅 www.adobe.com 以获取指南。
© 2024 Qt 公司有限公司。本文档中的文档贡献者是其各自业主的版权。本提供的文档是根据自由软件基金会发布的 GNU自由文档许可证版本1.3 的条款许可的。Qt及其相应徽标是芬兰以及全球其他地区的 Qt 公司有限公司的商标。所有其他商标均为其各自业主的财产。