Поддержка печати 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 Licensing.
Обратите внимание, что 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/qt-5.12/qtprintsupport-index.html