Qt Print Support

Qt Print Support 模块为打印提供广泛跨平台支持。使用各平台的打印系统,Qt 应用程序可以打印到附加打印机,和跨网络打印到远程打印机。打印系统还支持 PDF 文件生成,为基本报告生成设施提供基础。

Qt Print Support is not available on iOS.

支持打印的类

以下类支持打印机的选择、设置及打印输出。

QAbstractPrintDialog 为用于配置打印机的打印对话框的基实现
QPageRanges 表示页面范围的集合
QPageSetupDialog 用于打印机页面相关选项的配置对话框
QPrintDialog 用于指定打印机配置的对话框
QPrintEngine 定义 QPrinter 如何与给定打印子系统交互的接口
QPrintPreviewDialog 为打印机输出而预览和配置页面布局的 Widget
QPrintPreviewWidget 为打印机输出而预览页面布局的 Widget
QPrinter 在打印机上描绘的描绘设备
QPrinterInfo 给予访问现有打印机的有关信息

描绘设备和打印

打印机的表示通过 QPrinter ,描绘设备提供特定打印功能 (譬如:支持多页和双面输出)。因此,打印涉及使用 QPainter 以如在自定义 Widget 或图像上描绘的相同方式,在一系列页面上描绘。

创建 QPrinter

尽管 QPrinter 对象不要求用户输入就可以被构建和设置,打印经常是根据用户的请求而履行的;例如,当用户选择 File|Print... 菜单项在 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 to 写入本地文件 默认情况下而不是打印机。

在页面上描绘

一旦 QPrinter 对象被构建并设置, QPainter 可以用来在其上履行描绘操作。可以按以下方式构造和设置描绘器:

    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 () function after drawing each page, except for the last page.

文档被发送给打印机 (或写入本地文件),当我们调用 end ().

坐标系

QPrinter provides functions that can be used to obtain information about the dimensions of the paper (the paper rectangle) and the dimensions of the printable area (the page rectangle). These are given in logical device coordinates that may differ from the physical coordinates used by the device itself, indicating that the printer is able to render text and graphics at a (typically higher) resolution than the user's display.

Although we do not need to handle the conversion between logical and physical coordinates ourselves, we still need to apply transformations to painting operations because the pixel measurements used to draw on screen are often too small for the higher resolutions of typical printers.

打印机和描绘器坐标系

The paperRect () 和 pageRect () functions provide information about the size of the paper used for printing and the area on it that can be painted on.

The rectangle returned by pageRect () usually lies inside the rectangle returned by paperRect (). You do not need to take the positions and sizes of these area into account when using a QPainter 采用 QPrinter as the underlying paint device; the origin of the painter's coordinate system will coincide with the top-left corner of the page rectangle, and painting operations will be clipped to the bounds of the drawable part of the page.

The paint system automatically uses the correct device metrics when painting text but, if you need to position text using information obtained from font metrics, you need to ensure that the print device is specified when you construct QFontMetrics and QFontMetricsF objects, or ensure that each QFont used is constructed using the form of the constructor that accepts a QPaintDevice 自变量。

打印 Widget

要打印 Widget,可以使用 QWidget::render () 函数。如前所述,打印机分辨率通常高于屏幕分辨率,因此您必须缩放描绘器。您可能还想要在页面上放置 Widget。以下代码范例展示这可能看起来如何。

        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);
						

这将使 Widget 页面居中并缩放以使其拟合页面。

从复杂 Widget 打印

某些 Widget,譬如 QTextEdit and QGraphicsView , display rich content that is typically managed by instances of other classes, such as QTextDocument and QGraphicsScene . As a result, it is these content handling classes that usually provide printing functionality, either via a function that can be used to perform the complete task, or via a function that accepts an existing QPainter object. Some widgets provide convenience functions to expose underlying printing features, avoiding the need to obtain the content handler just to call a single function.

The following table shows which class and function are responsible for printing from a selection of different widgets. For widgets that do not expose printing functionality directly, the content handling classes containing this functionality can be obtained via a function in the corresponding widget's API.

Widget 打印函数 接受
QGraphicsView QGraphicsView::render () QPainter
QSvgWidget QSvgRenderer::render() QPainter
QTextEdit QTextDocument::print () QPrinter
QTextLayout QTextLayout::draw () QPainter
QTextLine QTextLine::draw () QPainter

QTextEdit requires a QPrinter rather than a QPainter because it uses information about the configured page dimensions in order to insert page breaks at the most appropriate places in printed documents.

使用模块

使用 Qt 模块要求直接或透过其它依赖链接到模块库。一些构建工具为此有贡献支持,包括 CMake and qmake .

构建采用 CMake

使用 find_package() 命令去定位所需模块组件,在 Qt6 包:

find_package(Qt6 REQUIRED COMPONENTS PrintSupport)
target_link_libraries(mytarget PRIVATE Qt6::PrintSupport)
						

另请参阅 构建采用 CMake 概述。

采用 qmake 构建

要配置采用 qmake 构建模块,添加模块作为值为 QT 变量在工程的 .pro 文件:

QT += printsupport
						

模块演变

Qt Print Support 的变化 列出了 Qt 的 Qt 6 系列在模块 API 和功能上所做出的重要改变。

许可和商标

Qt Print Support 模块在商业许可下是可用的来自 Qt 公司 。此外,它在自由软件许可下也是可用的: GNU LGPL (次一般公共许可) 第 3 版 ,或 GNU GPL (一般公共许可) 第 2 版 。见 Qt 许可 进一步了解细节。

Please note that Adobe ® places restrictions on the use of its trademarks (including logos) in conjunction with PDF; e.g. "Adobe PDF". Please refer to www.adobe.com for guidelines.