Введение
Пользователи иногда хотят распечатать конкретную страницу справки или сохранить её как PDF для последующего использования без необходимости держать приложение открытым — например, при настройке оборудования без доступа к компьютеру рядом. В статье добавим возможность печати и экспорта в PDF к справочному браузеру, построенному в статье 165, используя инфраструктуру печати Qt, более подробно разбираемую в отдельном цикле статей про печать и PDF.
Концепция
QTextBrowser наследует QTextEdit, который поддерживает печать своего содержимого через стандартный механизм QTextDocument::print() — документ, лежащий в основе браузера, можно напрямую отправить на QPrinter (показывая диалог печати пользователю) или на QPdfWriter (для прямого сохранения в PDF без диалога принтера). Поскольку базовый текстовый движок Qt используется и в QTextBrowser, и в общей системе печати, эта интеграция не требует какого-то специального кода, разбирающего HTML заново — печатается ровно то же отрендеренное представление документа, что показывается на экране.
Пример кода: Печать страниц справки
#include "helpwindow.h"
#include <QPrinter>
#include <QPrintDialog>
#include <QFileDialog>
#include <QPdfWriter>
void HelpWindow::onPrintCurrentPage()
{
QPrinter printer(QPrinter::HighResolution);
QPrintDialog dialog(&printer, this);
dialog.setWindowTitle("Печать страницы справки");
if (dialog.exec() != QDialog::Accepted) {
return;
}
m_browser->document()->print(&printer);
}
void HelpWindow::onExportCurrentPageToPdf()
{
const QString defaultName = m_browser->documentTitle().isEmpty()
? "справка.pdf"
: m_browser->documentTitle() + ".pdf";
const QString filePath = QFileDialog::getSaveFileName(
this, "Сохранить страницу справки как PDF", defaultName, "PDF файлы (*.pdf)");
if (filePath.isEmpty()) {
return;
}
QPdfWriter pdfWriter(filePath);
pdfWriter.setPageSize(QPageSize(QPageSize::A4));
pdfWriter.setResolution(300);
m_browser->document()->print(&pdfWriter);
qDebug() << "Страница справки сохранена как PDF:" << filePath;
}
// Добавление кнопок в панель инструментов окна справки (расширение HelpWindow из статьи 165)
auto *toolbar = addToolBar("Действия");
toolbar->addAction("Печать", this, &HelpWindow::onPrintCurrentPage);
toolbar->addAction("Сохранить как PDF", this, &HelpWindow::onExportCurrentPageToPdf);
Пояснения к коду
onPrintCurrentPage() создаёт стандартный QPrintDialog, позволяющий пользователю выбрать принтер и настройки печати, а затем вызывает m_browser->document()->print(&printer) — это печатает именно тот документ (с уже разрешёнными изображениями через loadResource(), как было настроено в статье 165), который в данный момент отображается в браузере, со всем форматированием.
onExportCurrentPageToPdf() показывает альтернативный путь без диалога принтера — QPdfWriter, настроенный на конкретный размер страницы и разрешение, передаётся в тот же метод print(), и результат сохраняется напрямую в выбранный пользователем файл через QFileDialog::getSaveFileName(). Использование m_browser->documentTitle() для формирования предложенного имени файла — приятная деталь UX, избавляющая пользователя от необходимости придумывать имя файла самостоятельно.
Подводные камни
- Печать только текущей видимой страницы, а не всей справки целиком. Пользователь, желающий распечатать «всю справку» или конкретный раздел с подразделами, должен будет повторить операцию для каждой страницы по отдельности — для печати целых разделов целиком нужна отдельная функциональность, которая бы программно «склеивала» содержимое нескольких страниц в один
QTextDocumentперед печатью, что не реализовано в базовом варианте. - Изображения, встроенные через схему
qthelp://, должны быть полностью загружены к моменту печати. Если печать инициируется до того, как все ресурсы текущей страницы успели разрешиться черезloadResource()(что обычно происходит синхронно и быстро для локального контента .qch, но стоит иметь в виду как потенциальный источник проблем), на печатной версии могут отсутствовать изображения. - Разрешение PDF, не соответствующее ожиданиям при последующем масштабировании. Установка
setResolution(300)определяет качество растеризации содержимого при экспорте — для текстовой справки без сложной растровой графики это обычно избыточно высокое значение, увеличивающее размер итогового файла без видимого выигрыша в качестве, тогда как для страниц с детальными скриншотами интерфейса более высокое разрешение действительно может быть оправдано. - Отсутствие поддержки печати интерактивных элементов, если справка содержит встроенное видео или интерактивные виджеты (актуально при использовании
QWebEngineViewвместоQTextBrowser, статья 172) — печать черезQTextDocument::print()работает только для контента, представимого в виде текстового документа, и не применима напрямую кWebEngineView, для которого нужен отдельный API печати (QWebEnginePage::printToPdf()), не совпадающий с показанным в этой статье подходом.