23 января 2017 года вышла Qt версии 5.8, в которой появилась поддержка печати полноценных HTML-документов.
До этого возможность напечатать документ тоже была. Можно было:
- Использовать метод QTextDocument::Print(). Но приходилось ограничиваться небольшими возможностями HTML и CSS.
- Использовать метод QWebFrame::print(), который существовал пока не вышла Qt 5.6. Потом в Qt был окончательно заменен веб-движок и поддержка печати пропала.
- Использовать печать в PDF с помощью метода QWebEnginePage::printToPdf(), который появился в Qt 5.7. Но печать в PDF — это не печать через принтер.
- Вывести видимую часть страницы на печать методом QWebEngineView->render(). Но это плохой обходной путь, так как не вся страница будет выведена на печать и потребуется отобразить страницу.
В Qt 5.8 появился метод QWebEnginePage::print(), который выводит на печать HTML-документы без отрисовки в окне и поддерживает современные возможности HTML, CSS и JavaScript.
Следующий код выводит HTML-документ на принтер.
#include <QDebug> #include <QPrinter> #include <QPrintDialog> #include <QPrinterInfo> #include <QWebEnginePage> void MainWindow::on_printButton_clicked() { QPrinter * printer = new QPrinter(); QPrintDialog printDialog(printer, this); if (printDialog.exec() != QDialog::Accepted) { return; } QWebEnginePage * page = new QWebEnginePage; page->setHtml("<html><body>Привет<body/></html>"); connect( page, &QWebEnginePage::loadFinished, [page, printer] (bool ok) { if (!ok) { qDebug() << "Загрузка документа провалилась."; delete page; delete printer; return; } page->print(printer, [page, printer](bool ok) { if (ok) { qDebug() << "Документ напечатан."; } else { qDebug() << "Печать документа провалилась."; } delete page; delete printer; }); } ); }
В файле проекта (*.pro) нужно подключить два модуля с помощью следующей строчки.
QT += printsupport webenginewidgets
В коде используются лямбда-выражения, которые появились в C++11. Это конструкции вида: [...] (...) {...}
, анонимные функции внутри функций. В Qt 5.8 по умолчанию включен C++11.
Класс QWebEnginePage обрабатывает, отрисовывает и печатает документы асинхронно с основным кодом программы, поэтому код в лямбда-функциях выполняется уже после того, как завершится метод on_printButton_clicked().
Надо внимательно следить за удалением объектов, чтобы не возникло утечки памяти и ошибки сегментации, особенно при печати нескольких документов в цикле. Объект принтера может быть одним, а выводимых на печать документов несколько. Тогда объект принтера надо удалять, после печати последнего документа, и не забывать, что печать происходит асинхронно. То есть функция print() завершается еще до вывода документа на печать.
Но и у этого способа печати есть огромный недостаток. К сожалению модуль Qt WebEngine, в который входит класс QWebEnginePage, недоступен при сборке проекта с помощью MinGW в Виндовс. Собрать проект в Виндовс можно только с помощью Visual Studio.