Поддержка печати Qt
Qt предоставляет обширную кроссплатформенную поддержку печати. Используя системы печати каждой платформы, приложения Qt могут печатать на подключенных принтерах и через сеть на удаленных принтерах. Система печати Qt также поддерживает создание файлов PDF, обеспечивая основу для базовых средств генерации отчетов.
Классы, поддерживающие печать
Следующие классы поддерживают выбор и настройку принтеров и выходных данных печати.
Базовая реализация диалогов печати, используемых для настройки принтеров |
|
Диалоговое окно для настройки параметров страницы на принтере |
|
Диалоговое окно для указания конфигурации принтера |
|
Определяет интерфейс взаимодействия QPrinter с заданной системой печати |
|
Диалоговое окно для предварительного просмотра и настройки макета страниц для вывода на принтер |
|
Элемент управления для предварительного просмотра макета страниц для вывода на принтер |
|
Устройство рисования, рисующее на принтере |
|
Предоставляет доступ к информации о существующих принтерах |
Устройства рисования и печать
В Qt принтеры представлены объектом QPrinter, устройством рисования, предоставляющим функциональность, специфичную для печати, такую как поддержка нескольких страниц и двусторонней печати. В результате, печать включает использование QPainter для рисования на серии страниц аналогично тому, как вы рисуете на пользовательском виджете или изображении.
Создание QPrinter
Хотя объекты QPrinter можно создавать и настраивать без необходимости ввода пользователя, печать часто выполняется по запросу пользователя; например, при выборе пункта меню Файл|Печать... в приложении графического интерфейса. В таких случаях новый созданный объект 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 можно использовать 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() после отрисовки каждой страницы, за исключением последней страницы.
Документ отправляется на принтер или записывается в локальный файл при вызове end().
Системы координат
QPrinter предоставляет функции, которые могут быть использованы для получения информации о размерах бумаги (прямоугольник бумаги) и размерах печатаемой области (прямоугольник страницы). Эти размеры заданы в логических координатах устройства, которые могут отличаться от физических координат, используемых самим устройством, что указывает на возможность принтера отображать текст и графику с (как правило, более высоким) разрешением, чем разрешение экрана пользователя.
Хотя нам не нужно самим обрабатывать преобразование между логическими и физическими координатами, нам все равно необходимо применять преобразования к операциям рисования, потому что пиксельные измерения, используемые для рисования на экране, часто слишком малы для более высокого разрешения типичных принтеров.
|
Системы координат принтера и рисовальщика Функции paperRect() и pageRect() предоставляют информацию о размере бумаги, используемой для печати, и области на ней, на которой можно рисовать. Прямоугольник, возвращаемый функцией pageRect(), обычно находится внутри прямоугольника, возвращаемого функцией paperRect(). Вам не нужно учитывать положения и размеры этих областей при использовании QPainter с QPrinter в качестве основного устройства рисования; начало системы координат рисовальщика будет совпадать с верхним левым углом прямоугольника страницы, а операции рисования будут обрезаны до границ отображаемой части страницы. |
Система рисования автоматически использует правильные метрики устройства при рисовании текста, но если вам нужно позиционировать текст, используя информацию, полученную из метрик шрифтов, необходимо убедиться, что устройство печати указано при создании объектов QFontMetrics и QFontMetricsF, или убедиться, что каждый используемый объект QFont создается с использованием формы конструктора, принимающего аргумент QPaintDevice.
Печать виджетов
Для печати виджета можно использовать функцию QWidget::render(). Как упоминалось ранее, разрешение принтера обычно выше, чем разрешение экрана, поэтому вам придется масштабировать рисовальщик. Также может потребоваться позиционировать виджет на странице. Следующий пример кода показывает, как это может выглядеть.
QPainter painter;
painter.begin(&printer);
double xscale = printer.pageRect().width()/double(myWidget->width());
double yscale = printer.pageRect().height()/double(myWidget->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(-width()/2, -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 доступен по коммерческим лицензиям от The Qt Company. Кроме того, он доступен по лицензиям свободного программного обеспечения. Начиная с Qt 5.4, эти лицензии свободного программного обеспечения являются GNU Lesser General Public License, версия 3 или GNU General Public License, версия 2. См. Лицензирование Qt для получения дополнительной информации.
Обратите внимание, что Adobe® устанавливает ограничения на использование своих товарных знаков (включая логотипы) в сочетании с PDF; например, «Adobe PDF». Обратитесь к www.adobe.com за рекомендациями.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/archives/qt-5.11/qtprintsupport-index.html