Search code examples
c++qtqwebengineview

QwebEnginePage Doesn't print html code Qt


I Trying print Html using qwebenginepage but not working i searched a lot to resolve this problem but didn't found the answer .

i was use QTextBrowser But when print it change style of page so i trying with qwebenginepage

QWebEnginePage *view = new QWebEnginePage;
QFile file("/home/hackerpoint/Desktop/some.html");
if(file.open(QIODevice::Text | QIODevice::ReadOnly)){
    QString html = file.readAll();
    QPrinter print(QPrinter::HighResolution);
    print.setPageSize(QPrinter::A4);
    print.setFullPage(true);
    print.setOutputFormat(QPrinter::PdfFormat);
    print.setOutputFileName("somefile.pdf");
    view->setHtml(html);
    if(&QWebEnginePage::loadFinished){
        view->print(&print , [=](bool){});
    }
    else {
        qInfo() << "Html Not loaded";
    }
}

and this the error

1  QPrinter::toPage() const                                                                      
2 QtWebEngineCore::PrinterWorker::print()                                                
3  QtWebEngineCore::PrinterWorker::qt_static_metacall(QObject *, QMetaObject::Call, int, void * *)
4  QObject::event(QEvent *)                                                                        
5  QApplicationPrivate::notify_helper(QObject *, QEvent *)                                         
6  QApplication::notify(QObject *, QEvent *)                                                       
7  QCoreApplication::notifyInternal2(QObject *, QEvent *)                                         
8  QCoreApplicationPrivate::sendPostedEvents(QObject *, int, QThreadData *)                        
9  postEventSourceDispatch(_GSource *, int ( *)(void *), void *)                                   
10 g_main_context_dispatch                                                                         
11 ___lldb_unnamed_symbol354$$libglib-2.0.so.0                                                     
12 g_main_context_iteration                                                                        
13 QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>)                      
14 QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>)                                         
15 QThread::exec()                                                                                 
16 QThreadPrivate::start(void *)                                                                   
17 start_thread                                                                                    
18 __GI___clone                                                                                    

Solution

  • You are confusing concepts: loadFinished is a signal and doing if(&QWebEnginePage::loadFinished) does not make sense (I recommend you review the basic concepts of signals and slots since it is the basis of Qt: https://doc.qt.io/qt-5/signalsandslots.html).

    On the other hand, it is not necessary to load the html as a file since you can pass it a url.

    Considering the above, the following code is a trivial example of how to print:

    #include <QtWebEngineWidgets>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        QWebEnginePage page;
        QPrinter printer(QPrinter::HighResolution);
        printer.setPageSize(QPrinter::A4);
        printer.setFullPage(true);
        printer.setOutputFormat(QPrinter::PdfFormat);
        printer.setOutputFileName("somefile.pdf");
        QObject::connect(&page, &QWebEnginePage::loadFinished, [&page, &printer](bool ok){
            if(ok){
                page.print(&printer, [](bool ok){
                    qDebug() << "printed " << ok;
                    QCoreApplication::quit();
                });
            }
            else{
                qDebug() << "Html Not loaded";
                QCoreApplication::exit(-1);
            }
        });
        page.load(QUrl::fromLocalFile("/home/hackerpoint/Desktop/some.html"));
        return a.exec();
    }
    

    UPDATE:

    Printer class

    #ifndef PRINTER_H
    #define PRINTER_H
    
    #include <QObject>
    #include <QPrinter>
    #include <QWebEnginePage>
    
    class Printer: public QObject
    {
        Q_OBJECT
    public:
        enum PrinterError{
            NoError = 0,
            LoadError,
            PrintError
        };
        Q_ENUM(PrinterError);
        Printer(QObject *parent=nullptr);
    public Q_SLOTS:
        void print(const QString & html, const QUrl &baseUrl=QUrl());
        void print(const QUrl & url);
    Q_SIGNALS:
        void finished();
        void error(PrinterError error);
    private Q_SLOTS:
        void onFinished(bool ok);
    private:
        QPrinter printer;
        QWebEnginePage page;
    };
    
    #endif // PRINTER_H
    
    #include "printer.h"
    
    Printer::Printer(QObject *parent):QObject(parent)
    {
        printer.setResolution(QPrinter::HighResolution);
        printer.setPageSize(QPrinter::A4);
        printer.setFullPage(true);
        printer.setOutputFormat(QPrinter::PdfFormat);
        printer.setOutputFileName("somefile.pdf");
        connect(&page, &QWebEnginePage::loadFinished, this, &Printer::onFinished);
    }
    
    void Printer::print(const QString &html, const QUrl & baseUrl)
    {
        page.setHtml(html, baseUrl);
    }
    
    void Printer::print(const QUrl &url)
    {
        page.load(url);
    }
    
    void Printer::onFinished(bool ok)
    {
        if(ok){
            page.print(&printer, [this](bool ok){
                if(ok)
                    Q_EMIT finished();
                else
                    Q_EMIT error(PrintError);
            });
        }
        else
            Q_EMIT error(LoadError);
    }
    

    MainWindow class:

    // ...
    private slots:
        void on_pushButton_clicked();
        void printError(Printer::PrinterError error);
        void printFinished();
    private:
        Ui::MainWindow *ui;
        Printer printer;
    // ...
    
    // ...
        ui->setupUi(this);
        connect(&printer, &Printer::finished, this, &MainWindow::printFinished);
        connect(&printer, &Printer::error, this, &MainWindow::printError);
    // ...
    void MainWindow::on_pushButton_clicked()
    {
        printer.print(QUrl::fromLocalFile("/home/hackerpoint/Desktop/some.html"));
    }
    
    void MainWindow::printError(Printer::PrinterError error)
    {
      if(error == Printer::LoadError){
          qDebug() << "Html Not loaded";
      }
      else if(error == Printer::PrintError){
          qDebug() << "Html Not printed";
      }
    }
    
    void MainWindow::printFinished()
    {
        qDebug() << "printed";
    }