Поддержка печати в 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, потому что он использует информацию о конфигурированных размерах страницы для вставки разрывов страниц в наиболее подходящих местах в печатных документах.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/archives/qt-5.6/qtprintsupport-index.html