Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt WebKit
  4. QWebEngineView. Can't replace html code and print new pdf
Forum Updated to NodeBB v4.3 + New Features

QWebEngineView. Can't replace html code and print new pdf

Scheduled Pinned Locked Moved Solved Qt WebKit
3 Posts 2 Posters 1.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • 0 Offline
    0 Offline
    0x5FB5
    wrote on 12 Dec 2022, 07:42 last edited by
    #1

    I have 2 small html files. I've printed the first page successfully, but if I call ...->setHtml again and place html code from another file and call printToPdf with a little modified filename, I see only the first file that was saved before. I've tested and on first pass it prints both htmls successfully. What's wrong?

    Here's the code:

    QFile file("://cards_src/dentist_043_header.html");
    file.open(QIODevice::ReadOnly);
    
    QTextStream input(&file);
    QString html = input.readAll();
    
    file.close();
    
    QFile file1("://cards_src/second_page_test.html");
    file1.open(QIODevice::ReadOnly);
    
    QTextStream input1(&file1);
    QString html1 = input1.readAll();
    
    file1.close();
    
    // do some things
     ...
    
    webView->setHtml(html);
    
    QString path = QFileDialog::getSaveFileName(nullptr, "Сохранить в PDF", fileName + ".pdf", "PDF (*.pdf)");
    
    if (QFileInfo(path).suffix().isEmpty())
        path.append(".pdf");
    
    webView->page()->printToPdf(path);
    webView->setHtml(html1);
    
    path.replace(".pdf", "_1.pdf");
    
    webView->page()->printToPdf(path);
    
    J 1 Reply Last reply 12 Dec 2022, 12:42
    0
    • J JonB
      12 Dec 2022, 12:42

      @0x5FB5
      I don't use QWebView so this is a guess. I wonder whether printToPdf() doesn't happen in the backgroubnd/asynchronously? In which case the web view's HTML must stay the same until the printing has finished? Only then can you change to a new HTML and print that. See e.g. https://stackoverflow.com/questions/59274653/how-to-print-from-qwebengineview. Use QWebEngineView::loadFinished to wait for HTML to be loaded before printing? Or is there a "print finished" signal from printToPdf() which you must wait for before proceeding with the second page?

      0 Offline
      0 Offline
      0x5FB5
      wrote on 12 Dec 2022, 16:22 last edited by 0x5FB5
      #3

      @JonB Yep, I've just found that I need to wait for loading page before printing and the solution is connect loadFinished signal to method I need, that do printToPdf() in it. I thought that WebEngineView does not need to wait for the local html file to load, but it was mistaken.

      UPD: Also, I've found a way to print multiple pdfs. You need to make a QEventLoop obj, connect loadFinished signal to QEventLoop::quit and after setHtml just call loop.exec() and you can guarantee that file you need will load and prints correctly only after loading of the previous page code.

      Example:

      // Header
      class MyClass : public QObject
      {
          Q_OBJECT
      
      private:
          QEventLoop loop;
          QWebEngineView *webView;
      
      public:
          void saveCardPdf();
      
      // Cpp
      MyClass::MyClass(QObject *parent ): QObject(parent)
      {
          webView = new QWebEngineView();
          connect(webView, &QWebEngineView::loadFinished, &loop, &QEventLoop::quit);
      }
      
      ...
      void MyClass::saveCardPdf()
      {
          ...
          // Load your html code..
      
          webView->setHtml(html); // html - string of one page
          loop.exec();
      
          webView->page()->printToPdf(path);
      
          // Modify name for another file
          path.replace(".pdf", "_1.pdf");
      
          webView->setHtml(html1); // html1 - string of another page
          loop.exec();
      
          webView->page()->printToPdf(path);
      }
      

      It's not perfect solution, but I think you understand the idea

      1 Reply Last reply
      3
      • 0 0x5FB5
        12 Dec 2022, 07:42

        I have 2 small html files. I've printed the first page successfully, but if I call ...->setHtml again and place html code from another file and call printToPdf with a little modified filename, I see only the first file that was saved before. I've tested and on first pass it prints both htmls successfully. What's wrong?

        Here's the code:

        QFile file("://cards_src/dentist_043_header.html");
        file.open(QIODevice::ReadOnly);
        
        QTextStream input(&file);
        QString html = input.readAll();
        
        file.close();
        
        QFile file1("://cards_src/second_page_test.html");
        file1.open(QIODevice::ReadOnly);
        
        QTextStream input1(&file1);
        QString html1 = input1.readAll();
        
        file1.close();
        
        // do some things
         ...
        
        webView->setHtml(html);
        
        QString path = QFileDialog::getSaveFileName(nullptr, "Сохранить в PDF", fileName + ".pdf", "PDF (*.pdf)");
        
        if (QFileInfo(path).suffix().isEmpty())
            path.append(".pdf");
        
        webView->page()->printToPdf(path);
        webView->setHtml(html1);
        
        path.replace(".pdf", "_1.pdf");
        
        webView->page()->printToPdf(path);
        
        J Offline
        J Offline
        JonB
        wrote on 12 Dec 2022, 12:42 last edited by
        #2

        @0x5FB5
        I don't use QWebView so this is a guess. I wonder whether printToPdf() doesn't happen in the backgroubnd/asynchronously? In which case the web view's HTML must stay the same until the printing has finished? Only then can you change to a new HTML and print that. See e.g. https://stackoverflow.com/questions/59274653/how-to-print-from-qwebengineview. Use QWebEngineView::loadFinished to wait for HTML to be loaded before printing? Or is there a "print finished" signal from printToPdf() which you must wait for before proceeding with the second page?

        0 1 Reply Last reply 12 Dec 2022, 16:22
        1
        • J JonB
          12 Dec 2022, 12:42

          @0x5FB5
          I don't use QWebView so this is a guess. I wonder whether printToPdf() doesn't happen in the backgroubnd/asynchronously? In which case the web view's HTML must stay the same until the printing has finished? Only then can you change to a new HTML and print that. See e.g. https://stackoverflow.com/questions/59274653/how-to-print-from-qwebengineview. Use QWebEngineView::loadFinished to wait for HTML to be loaded before printing? Or is there a "print finished" signal from printToPdf() which you must wait for before proceeding with the second page?

          0 Offline
          0 Offline
          0x5FB5
          wrote on 12 Dec 2022, 16:22 last edited by 0x5FB5
          #3

          @JonB Yep, I've just found that I need to wait for loading page before printing and the solution is connect loadFinished signal to method I need, that do printToPdf() in it. I thought that WebEngineView does not need to wait for the local html file to load, but it was mistaken.

          UPD: Also, I've found a way to print multiple pdfs. You need to make a QEventLoop obj, connect loadFinished signal to QEventLoop::quit and after setHtml just call loop.exec() and you can guarantee that file you need will load and prints correctly only after loading of the previous page code.

          Example:

          // Header
          class MyClass : public QObject
          {
              Q_OBJECT
          
          private:
              QEventLoop loop;
              QWebEngineView *webView;
          
          public:
              void saveCardPdf();
          
          // Cpp
          MyClass::MyClass(QObject *parent ): QObject(parent)
          {
              webView = new QWebEngineView();
              connect(webView, &QWebEngineView::loadFinished, &loop, &QEventLoop::quit);
          }
          
          ...
          void MyClass::saveCardPdf()
          {
              ...
              // Load your html code..
          
              webView->setHtml(html); // html - string of one page
              loop.exec();
          
              webView->page()->printToPdf(path);
          
              // Modify name for another file
              path.replace(".pdf", "_1.pdf");
          
              webView->setHtml(html1); // html1 - string of another page
              loop.exec();
          
              webView->page()->printToPdf(path);
          }
          

          It's not perfect solution, but I think you understand the idea

          1 Reply Last reply
          3

          1/3

          12 Dec 2022, 07:42

          • Login

          • Login or register to search.
          1 out of 3
          • First post
            1/3
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved