How to print from QWebEngineView

前端 未结 1 1727
我寻月下人不归
我寻月下人不归 2021-01-24 17:05

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

相关标签:
1条回答
  • 2021-01-24 17:29

    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 <QtWebEngineWidgets>
    
    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"(<!DOCTYPE html>
                           <html>
                           <head>
                           <style>
                           table {
                           font-family: arial, sans-serif;
                           border-collapse: collapse;
                           width: 100%;
                           }
    
                           td, th {
                           border: 1px solid #ffffdffffd;
                           text-align: left;
                           padding: 8px;
                           }
    
                           tr:nth-child(even) {
                           background-color: #ffffdffffd;
                           }
                           </style>
                           </head>
                           <body>
    
                           <h2>HTML Table</h2>
    
                           <table>
                           <tr>
                           <th>Company</th>
                           <th>Contact</th>
                           <th>Country</th>
                           </tr>
                           <tr>
                           <td>Alfreds Futterkiste</td>
                           <td>Maria Anders</td>
                           <td>Germany</td>
                           </tr>
                           <tr>
                           <td>Centro comercial Moctezuma</td>
                           <td>Francisco Chang</td>
                           <td>Mexico</td>
                           </tr>
                           <tr>
                           <td>Ernst Handel</td>
                           <td>Roland Mendel</td>
                           <td>Austria</td>
                           </tr>
                           <tr>
                           <td>Island Trading</td>
                           <td>Helen Bennett</td>
                           <td>UK</td>
                           </tr>
                           <tr>
                           <td>Laughing Bacchus Winecellars</td>
                           <td>Yoshi Tannamuri</td>
                           <td>Canada</td>
                           </tr>
                           <tr>
                           <td>Magazzini Alimentari Riuniti</td>
                           <td>Giovanni Rovelli</td>
                           <td>Italy</td>
                           </tr>
                           </table>
    
                           </body>
                           </html>
                           )";
    
            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 <QtWebEngineWidgets>
    
    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"(<!DOCTYPE html>
                           <html>
                           <head>
                           <style>
                           table {
                           font-family: arial, sans-serif;
                           border-collapse: collapse;
                           width: 100%;
                           }
    
                           td, th {
                           border: 1px solid #ffffdffffd;
                           text-align: left;
                           padding: 8px;
                           }
    
                           tr:nth-child(even) {
                           background-color: #ffffdffffd;
                           }
                           </style>
                           </head>
                           <body>
    
                           <h2>HTML Table</h2>
    
                           <table>
                           <tr>
                           <th>Company</th>
                           <th>Contact</th>
                           <th>Country</th>
                           </tr>
                           <tr>
                           <td>Alfreds Futterkiste</td>
                           <td>Maria Anders</td>
                           <td>Germany</td>
                           </tr>
                           <tr>
                           <td>Centro comercial Moctezuma</td>
                           <td>Francisco Chang</td>
                           <td>Mexico</td>
                           </tr>
                           <tr>
                           <td>Ernst Handel</td>
                           <td>Roland Mendel</td>
                           <td>Austria</td>
                           </tr>
                           <tr>
                           <td>Island Trading</td>
                           <td>Helen Bennett</td>
                           <td>UK</td>
                           </tr>
                           <tr>
                           <td>Laughing Bacchus Winecellars</td>
                           <td>Yoshi Tannamuri</td>
                           <td>Canada</td>
                           </tr>
                           <tr>
                           <td>Magazzini Alimentari Riuniti</td>
                           <td>Giovanni Rovelli</td>
                           <td>Italy</td>
                           </tr>
                           </table>
    
                           </body>
                           </html>
                           )";
    
            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();
    }
    
    0 讨论(0)
提交回复
热议问题