I am trying to print a report from within my application, which involves both text and tables. Since QTextDocument
won\'t be sufficient, I\'ve decided to go with
In the first approach I think it fails because the HTML or url is not loaded yet and you want to print the text, so a possible solution is to use the loadFinished signal to start printing and use pdfPrintingFinished to know when the printing is finished.
#include
class Widget : public QWidget
{
public:
explicit Widget(QWidget *parent = nullptr):
QWidget(parent), button(new QPushButton), progressbar(new QProgressBar), view(new QWebEngineView)
{
button->setText(tr("Press me"));
button->setEnabled(false);
connect(button, &QPushButton::clicked, this, &Widget::onClicked);
connect(view, &QWebEngineView::loadFinished, this, &Widget::onLoadFinished);
connect(view->page(), &QWebEnginePage::pdfPrintingFinished, this, &Widget::onPdfPrintingFinished);
QString html = R"(
HTML Table
Company
Contact
Country
Alfreds Futterkiste
Maria Anders
Germany
Centro comercial Moctezuma
Francisco Chang
Mexico
Ernst Handel
Roland Mendel
Austria
Island Trading
Helen Bennett
UK
Laughing Bacchus Winecellars
Yoshi Tannamuri
Canada
Magazzini Alimentari Riuniti
Giovanni Rovelli
Italy
)";
view->setHtml(html);
auto lay = new QVBoxLayout(this);
lay->addWidget(button);
lay->addWidget(progressbar);
lay->addWidget(view);
resize(640, 480);
}
private:
void onLoadFinished(bool ok){
button->setEnabled(ok);
}
void onClicked(){
progressbar->setRange(0, 0);
QString fn = "/Users/s710/Downloads/test.pdf";
view->page()->printToPdf(fn);
}
void onPdfPrintingFinished(const QString & filename, bool ok){
qDebug() << filename << ok;
progressbar->setRange(0, 1);
}
private:
QPushButton *button;
QProgressBar *progressbar;
QWebEngineView *view;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
In the case where you use QPrinter I think that the error is caused because QPrinter is a local variable that is eliminated when the function is finished executing but Qt tries to access that variable asynchronously but the object does not exist. The solution is to extend the scope of QPrinter.
#include
class Widget : public QWidget
{
public:
Widget(QWidget *parent = nullptr):
QWidget(parent), button(new QPushButton), progressbar(new QProgressBar), view(new QWebEngineView)
{
button->setText(tr("Press me"));
button->setEnabled(false);
connect(button, &QPushButton::clicked, this, &Widget::onClicked);
connect(view, &QWebEngineView::loadFinished, this, &Widget::onLoadFinished);
printer.setResolution(QPrinter::PrinterResolution);
printer.setOutputFormat(QPrinter::NativeFormat);
printer.setPaperSize(QPrinter::A4);
printer.setPageMargins(12, 16, 12, 20, QPrinter::Millimeter);
QString html = R"(
HTML Table
Company
Contact
Country
Alfreds Futterkiste
Maria Anders
Germany
Centro comercial Moctezuma
Francisco Chang
Mexico
Ernst Handel
Roland Mendel
Austria
Island Trading
Helen Bennett
UK
Laughing Bacchus Winecellars
Yoshi Tannamuri
Canada
Magazzini Alimentari Riuniti
Giovanni Rovelli
Italy
)";
view->setHtml(html);
auto lay = new QVBoxLayout(this);
lay->addWidget(button);
lay->addWidget(progressbar);
lay->addWidget(view);
resize(640, 480);
}
private:
void onLoadFinished(bool ok){
button->setEnabled(ok);
}
void onClicked(){
progressbar->setRange(0, 0);
QString fn = "/Users/s710/Downloads/test.pdf";
printer.setOutputFileName(fn);
view->page()->print(&printer, [this](bool ok){
qDebug() << ok;
progressbar->setRange(0, 1);
});
}
private:
QPushButton *button;
QProgressBar *progressbar;
QWebEngineView *view;
QPrinter printer;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}