Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. [Solved] How to take a Print in QML?
Forum Updated to NodeBB v4.3 + New Features

[Solved] How to take a Print in QML?

Scheduled Pinned Locked Moved QML and Qt Quick
15 Posts 3 Posters 20.4k Views 3 Watching
  • 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.
  • I IT MAN 2015

    @p3c0 said:

    Hi @IT-MAN-2015,
    QML doesnot have any such mechanism of printing. You will need to make use of Qt's C++ API's for actual printing. First you can grab image of any Item using grabToImage the result will be delegated to a callback. Inside it you can get the grabbed image data which is actually a QImage. Later you can send it to C++ side using signal/slot or by calling a Q_INVOKABLE function. Then use QPrinter to print that image.

    Well , for example I wrote this codes for webView but I can't get webView source for send to C++ function to print it.

    C++ Invokable function
    .h file

    #ifndef PR_H
    #define PR_H
    
    #include <QObject>
    
    
    class pr : public QObject
    {
        Q_OBJECT
    
    public:
        pr();
    
    public:
    
    Q_INVOKABLE  void print(QString url);
    
    
    };
    
    #endif // PR_H
    

    .cpp :

    void pr::print(QString url)
    
    {
    
        QString fileName = QFileDialog::getOpenFileName(0,"Open File",QString(),"PNG File(*.png)");
        QPrinter printer;
              QPrintDialog *dlg = new QPrintDialog(&printer,0);
              if(dlg->exec() == QDialog::Accepted) {
                      QImage img(fileName);
                      QPainter painter(&printer);
                      painter.drawImage(QPoint(0,0),img);
                      painter.end();
              }
    
    
    }
    

    main file :

    //For QML
    pr  print;
    
        engine.rootContext()->setContextProperty("PRINT", &print);
    

    QMl file :

                WebView {
                    id: result_view
                    x: 154
                    y: 22
                    url:"https://forum.qt.io/logo.png"
    
                }
    
            Button {
                id: button1
                x: 437
                y: 137
                width: 150
                height: 36
                text: qsTr("Print")
                onClicked: {
                    PRINT.print(/*My WebView Content*/);
                }
            }
    
    p3c0P Offline
    p3c0P Offline
    p3c0
    Moderators
    wrote on last edited by
    #4

    @IT-MAN-2015 As said earlier use grabToImage to grab a snapshot of the Item i.e in your case WebView. Then its result will give you QImage and then send it to C++. So instead of (QString url) as argument use QVariant and convert it to QImage. Following should work as per your code:

    WebView {
        id: webview
        anchors.fill: parent
        url: "https://forum.qt.io/logo.png"
    }
    
    Button {
        anchors.bottom: parent.bottom
        onClicked: {
            var stat = result_view.grabToImage(function(result) {
                //result.saveToFile("/home/user/someimage.png"); //saves to a file
                PRINT.print(result.image); //result.image holds the QVariant
            });
            console.log("Success: ", stat);
        }
    }
    

    157

    I 1 Reply Last reply
    1
    • p3c0P p3c0

      @IT-MAN-2015 As said earlier use grabToImage to grab a snapshot of the Item i.e in your case WebView. Then its result will give you QImage and then send it to C++. So instead of (QString url) as argument use QVariant and convert it to QImage. Following should work as per your code:

      WebView {
          id: webview
          anchors.fill: parent
          url: "https://forum.qt.io/logo.png"
      }
      
      Button {
          anchors.bottom: parent.bottom
          onClicked: {
              var stat = result_view.grabToImage(function(result) {
                  //result.saveToFile("/home/user/someimage.png"); //saves to a file
                  PRINT.print(result.image); //result.image holds the QVariant
              });
              console.log("Success: ", stat);
          }
      }
      
      I Offline
      I Offline
      IT MAN 2015
      wrote on last edited by p3c0
      #5

      @p3c0 said:

      @IT-MAN-2015 As said earlier use grabToImage to grab a snapshot of the Item i.e in your case WebView. Then its result will give you QImage and then send it to C++. So instead of (QString url) as argument use QVariant and convert it to QImage. Following should work as per your code:

      WebView {
          id: webview
          anchors.fill: parent
          url: "https://forum.qt.io/logo.png"
      }
      
      Button {
          anchors.bottom: parent.bottom
          onClicked: {
              var stat = result_view.grabToImage(function(result) {
                  //result.saveToFile("/home/user/someimage.png"); //saves to a file
                  PRINT.print(result.image); //result.image holds the QVariant
              });
              console.log("Success: ", stat);
          }
      }
      

      Thank you p3c0 for your helping.
      But I can't convert QVariant to QImage
      I think my function is wrong! QPrintDialog not work when I write custom path.

      void pr::print(QVariant *url)
      
      {
          //QString fileName = QFileDialog::getOpenFileName(0,"Open File",QString(),"PNG File(*.png)");
          QPrinter printer;
                QPrintDialog *dlg = new QPrintDialog(&printer,0);
                if(dlg->exec() == QDialog::Accepted) {
                   
                        //Convert my QVariant to image file
                        url->toImage ?!!? how convert to image :(
                    
                        QImage img(fileName);
                        QPainter painter(&printer);
                        painter.drawImage(QPoint(0,0),img);
                        painter.end();
                }
      }
      
      p3c0P 1 Reply Last reply
      0
      • I IT MAN 2015

        @p3c0 said:

        @IT-MAN-2015 As said earlier use grabToImage to grab a snapshot of the Item i.e in your case WebView. Then its result will give you QImage and then send it to C++. So instead of (QString url) as argument use QVariant and convert it to QImage. Following should work as per your code:

        WebView {
            id: webview
            anchors.fill: parent
            url: "https://forum.qt.io/logo.png"
        }
        
        Button {
            anchors.bottom: parent.bottom
            onClicked: {
                var stat = result_view.grabToImage(function(result) {
                    //result.saveToFile("/home/user/someimage.png"); //saves to a file
                    PRINT.print(result.image); //result.image holds the QVariant
                });
                console.log("Success: ", stat);
            }
        }
        

        Thank you p3c0 for your helping.
        But I can't convert QVariant to QImage
        I think my function is wrong! QPrintDialog not work when I write custom path.

        void pr::print(QVariant *url)
        
        {
            //QString fileName = QFileDialog::getOpenFileName(0,"Open File",QString(),"PNG File(*.png)");
            QPrinter printer;
                  QPrintDialog *dlg = new QPrintDialog(&printer,0);
                  if(dlg->exec() == QDialog::Accepted) {
                     
                          //Convert my QVariant to image file
                          url->toImage ?!!? how convert to image :(
                      
                          QImage img(fileName);
                          QPainter painter(&printer);
                          painter.drawImage(QPoint(0,0),img);
                          painter.end();
                  }
        }
        
        p3c0P Offline
        p3c0P Offline
        p3c0
        Moderators
        wrote on last edited by
        #6

        @IT-MAN-2015 Not need of QVariant pointer. It is implicily shared. Afterwards use qvariant_cast to cast it to QImage and then as usual of printing. So

        void pr::print(QVariant data) { //note: it sends a complete image and not just url
             QImage img = qvariant_cast<QImage>(data);
        }
        

        157

        I 1 Reply Last reply
        1
        • p3c0P p3c0

          @IT-MAN-2015 Not need of QVariant pointer. It is implicily shared. Afterwards use qvariant_cast to cast it to QImage and then as usual of printing. So

          void pr::print(QVariant data) { //note: it sends a complete image and not just url
               QImage img = qvariant_cast<QImage>(data);
          }
          
          I Offline
          I Offline
          IT MAN 2015
          wrote on last edited by p3c0
          #7

          @p3c0 said:

          @IT-MAN-2015 Not need of QVariant pointer. It is implicily shared. Afterwards use qvariant_cast to cast it to QImage and then as usual of printing. So

          void pr::print(QVariant data) { //note: it sends a complete image and not just url
               QImage img = qvariant_cast<QImage>(data);
          }
          

          Well... I understand about QVariant but now i get error !

          error: C2664: 'void pr::print(QVariant)' : cannot convert argument 1 from 'QVariant' to 'QVariant'
          Source or target has incomplete type

          .h file :

          #ifndef PR_H
          #define PR_H
          #include <QObject>
          class pr : public QObject
          {
              Q_OBJECT
          public:
              pr();
          public:
          Q_INVOKABLE void print(QVariant data);
          };
          #endif // PR_H
          

          and .cpp file :

          pr::pr()
          {
          }
          void pr::print(QVariant data)
          {
             QImage img = qvariant_cast<QImage>(data);
             QPrinter printer;
                    QPrintDialog *dlg = new QPrintDialog(&printer,0);
                    if(dlg->exec() == QDialog::Accepted) {
                            QPainter painter(&printer);
                            painter.drawImage(QPoint(0,0),img);
                            painter.end();
                    }
          }
          
          p3c0P 1 Reply Last reply
          0
          • timdayT Offline
            timdayT Offline
            timday
            wrote on last edited by
            #8

            It's worth mentioning this is one of the few things the old Qt4.8-era QDeclarativeView could do better, due to being QPainter based instead of OpenGL; see http://stackoverflow.com/questions/20825233/how-to-print-a-qquickviews-contents-to-pdf . (Well in theory; in practice the PDFs seemed to have some flaws.)

            The possibility of using the new (commerical license) QtQuick software rendering tech for improving print capabilities gets a brief mention in the thread under https://blog.qt.io/blog/2015/01/22/introducing-the-qt-quick-2d-renderer/ too.

            p3c0P 1 Reply Last reply
            0
            • I IT MAN 2015

              @p3c0 said:

              @IT-MAN-2015 Not need of QVariant pointer. It is implicily shared. Afterwards use qvariant_cast to cast it to QImage and then as usual of printing. So

              void pr::print(QVariant data) { //note: it sends a complete image and not just url
                   QImage img = qvariant_cast<QImage>(data);
              }
              

              Well... I understand about QVariant but now i get error !

              error: C2664: 'void pr::print(QVariant)' : cannot convert argument 1 from 'QVariant' to 'QVariant'
              Source or target has incomplete type

              .h file :

              #ifndef PR_H
              #define PR_H
              #include <QObject>
              class pr : public QObject
              {
                  Q_OBJECT
              public:
                  pr();
              public:
              Q_INVOKABLE void print(QVariant data);
              };
              #endif // PR_H
              

              and .cpp file :

              pr::pr()
              {
              }
              void pr::print(QVariant data)
              {
                 QImage img = qvariant_cast<QImage>(data);
                 QPrinter printer;
                        QPrintDialog *dlg = new QPrintDialog(&printer,0);
                        if(dlg->exec() == QDialog::Accepted) {
                                QPainter painter(&printer);
                                painter.drawImage(QPoint(0,0),img);
                                painter.end();
                        }
              }
              
              p3c0P Offline
              p3c0P Offline
              p3c0
              Moderators
              wrote on last edited by
              #9

              @IT-MAN-2015 do #include <QVariant>

              157

              I 1 Reply Last reply
              1
              • p3c0P p3c0

                @IT-MAN-2015 do #include <QVariant>

                I Offline
                I Offline
                IT MAN 2015
                wrote on last edited by
                #10

                @p3c0

                Thank you p30c0 :-) I understand and I can take a print in QML right now.
                Thank you for your helping my friend.

                p3c0P 1 Reply Last reply
                0
                • I IT MAN 2015

                  @p3c0

                  Thank you p30c0 :-) I understand and I can take a print in QML right now.
                  Thank you for your helping my friend.

                  p3c0P Offline
                  p3c0P Offline
                  p3c0
                  Moderators
                  wrote on last edited by
                  #11

                  @IT-MAN-2015 You're Welcome :) Also please surround you code with ``` (3 backticks) while posting here so that it gets formatted nicely and is more readable.

                  157

                  I 1 Reply Last reply
                  2
                  • timdayT timday

                    It's worth mentioning this is one of the few things the old Qt4.8-era QDeclarativeView could do better, due to being QPainter based instead of OpenGL; see http://stackoverflow.com/questions/20825233/how-to-print-a-qquickviews-contents-to-pdf . (Well in theory; in practice the PDFs seemed to have some flaws.)

                    The possibility of using the new (commerical license) QtQuick software rendering tech for improving print capabilities gets a brief mention in the thread under https://blog.qt.io/blog/2015/01/22/introducing-the-qt-quick-2d-renderer/ too.

                    p3c0P Offline
                    p3c0P Offline
                    p3c0
                    Moderators
                    wrote on last edited by
                    #12

                    @timday

                    It's worth mentioning this is one of the few things the old Qt4.8-era QDeclarativeView could do better, due to being QPainter based instead of OpenGL; see http://stackoverflow.com/questions/20825233/how-to-print-a-qquickviews-contents-to-pdf . (Well in theory; in practice the PDFs seemed to have some flaws.)

                    Yes indeed. Miss them for these features including WebView. I guess in future we may have a direct print function in QtQuick 2.x too.

                    157

                    1 Reply Last reply
                    1
                    • p3c0P p3c0

                      @IT-MAN-2015 You're Welcome :) Also please surround you code with ``` (3 backticks) while posting here so that it gets formatted nicely and is more readable.

                      I Offline
                      I Offline
                      IT MAN 2015
                      wrote on last edited by IT MAN 2015
                      #13

                      @p3c0 said:

                      @IT-MAN-2015 You're Welcome :) Also please surround you code with ``` (3 backticks) while posting here so that it gets formatted nicely and is more readable.

                      Here you are :

                      .h file

                      #ifndef PR_H
                      #define PR_H
                      
                      #include <QObject>
                      #include <QVariant>
                      
                      class pr : public QObject
                      {
                          Q_OBJECT
                      
                      public:
                          pr();
                      
                      public:
                      
                      Q_INVOKABLE void print(QVariant data);
                      
                      
                      };
                      
                      #endif // PR_H
                      

                      .cpp file :

                      #include "pr.h"
                      #include <QPrinter>
                      #include <QPainter>
                      #include <QPrintDialog>
                      #include <QPixmap>
                      #include <QImage>
                      #include <qDebug>
                      
                      pr::pr()
                      {
                      
                      }
                      
                      void pr::print(QVariant data)
                      
                      {
                      
                      
                          QImage img = qvariant_cast<QImage>(data);
                          QPrinter printer;
                                QPrintDialog *dlg = new QPrintDialog(&printer,0);
                                if(dlg->exec() == QDialog::Accepted) {
                                        QPainter painter(&printer);
                                        painter.drawImage(QPoint(0,0),img);
                                        painter.end();
                                }
                      
                      
                      }
                      
                      

                      QML file :

                                  WebView {
                                      id: result_view
                                      x: 154
                                      y: 22
                                      url:"http://forum.qt.io/logo.png"
                                      enabled: false
                                      antialiasing: true
                      
                                  }
                      
                      
                              Button {
                                  id: button1
                                  x: 437
                                  y: 137
                                  width: 150
                                  height: 36
                                  text: qsTr("Print")
                                  onClicked: {
                                          var stat = result_view.grabToImage(function(result) {
                                              //result.saveToFile("/home/user/someimage.png"); //saves to a file
                                              PRINT.print(result.image); //result.image holds the QVariant
                                          });
                                          console.log("Success: ", stat);
                                      }
                              }
                      
                      

                      main.cpp

                      #include <QApplication>
                      #include <QQmlApplicationEngine>
                      #include <QtWebEngine/QtWebEngine>
                      #include <pr.h>
                      
                      int main(int argc, char *argv[])
                      {
                          QApplication app(argc, argv);
                      
                          QQmlApplicationEngine engine;
                          QtWebEngine::initialize();
                      
                          //For QML
                          pr  print;
                          engine.rootContext()->setContextProperty("PRINT", &print);
                          engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                      
                          return app.exec();
                      }
                      
                      p3c0P 1 Reply Last reply
                      4
                      • I IT MAN 2015

                        @p3c0 said:

                        @IT-MAN-2015 You're Welcome :) Also please surround you code with ``` (3 backticks) while posting here so that it gets formatted nicely and is more readable.

                        Here you are :

                        .h file

                        #ifndef PR_H
                        #define PR_H
                        
                        #include <QObject>
                        #include <QVariant>
                        
                        class pr : public QObject
                        {
                            Q_OBJECT
                        
                        public:
                            pr();
                        
                        public:
                        
                        Q_INVOKABLE void print(QVariant data);
                        
                        
                        };
                        
                        #endif // PR_H
                        

                        .cpp file :

                        #include "pr.h"
                        #include <QPrinter>
                        #include <QPainter>
                        #include <QPrintDialog>
                        #include <QPixmap>
                        #include <QImage>
                        #include <qDebug>
                        
                        pr::pr()
                        {
                        
                        }
                        
                        void pr::print(QVariant data)
                        
                        {
                        
                        
                            QImage img = qvariant_cast<QImage>(data);
                            QPrinter printer;
                                  QPrintDialog *dlg = new QPrintDialog(&printer,0);
                                  if(dlg->exec() == QDialog::Accepted) {
                                          QPainter painter(&printer);
                                          painter.drawImage(QPoint(0,0),img);
                                          painter.end();
                                  }
                        
                        
                        }
                        
                        

                        QML file :

                                    WebView {
                                        id: result_view
                                        x: 154
                                        y: 22
                                        url:"http://forum.qt.io/logo.png"
                                        enabled: false
                                        antialiasing: true
                        
                                    }
                        
                        
                                Button {
                                    id: button1
                                    x: 437
                                    y: 137
                                    width: 150
                                    height: 36
                                    text: qsTr("Print")
                                    onClicked: {
                                            var stat = result_view.grabToImage(function(result) {
                                                //result.saveToFile("/home/user/someimage.png"); //saves to a file
                                                PRINT.print(result.image); //result.image holds the QVariant
                                            });
                                            console.log("Success: ", stat);
                                        }
                                }
                        
                        

                        main.cpp

                        #include <QApplication>
                        #include <QQmlApplicationEngine>
                        #include <QtWebEngine/QtWebEngine>
                        #include <pr.h>
                        
                        int main(int argc, char *argv[])
                        {
                            QApplication app(argc, argv);
                        
                            QQmlApplicationEngine engine;
                            QtWebEngine::initialize();
                        
                            //For QML
                            pr  print;
                            engine.rootContext()->setContextProperty("PRINT", &print);
                            engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                        
                            return app.exec();
                        }
                        
                        p3c0P Offline
                        p3c0P Offline
                        p3c0
                        Moderators
                        wrote on last edited by
                        #14

                        @IT-MAN-2015 Thanks for sharing :)

                        157

                        I 1 Reply Last reply
                        1
                        • p3c0P p3c0

                          @IT-MAN-2015 Thanks for sharing :)

                          I Offline
                          I Offline
                          IT MAN 2015
                          wrote on last edited by
                          #15

                          @p3c0 said:

                          @IT-MAN-2015 Thanks for sharing :)

                          You're welcome :)
                          Have a nice time.

                          1 Reply Last reply
                          1

                          • Login

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