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?
QtWS25 Last Chance

[Solved] How to take a Print in QML?

Scheduled Pinned Locked Moved QML and Qt Quick
15 Posts 3 Posters 20.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.
  • I Offline
    I Offline
    IT MAN 2015
    wrote on last edited by IT MAN 2015
    #1

    Hello ;
    I need to take a print in Qt Quick, So I Can't find any way to do this.
    Of course I checked this link : http://doc.qt.io/qt-5/qtprintsupport-index.html , but this work on widgets only not QML.

    So if anyone need to take print a page in QML how can do this ?
    for example I need take print from WebView content , TableView , Rectangle or other objects in QML.

    p3c0P 1 Reply Last reply
    0
    • I IT MAN 2015

      Hello ;
      I need to take a print in Qt Quick, So I Can't find any way to do this.
      Of course I checked this link : http://doc.qt.io/qt-5/qtprintsupport-index.html , but this work on widgets only not QML.

      So if anyone need to take print a page in QML how can do this ?
      for example I need take print from WebView content , TableView , Rectangle or other objects in QML.

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

      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.

      157

      I 1 Reply Last reply
      1
      • p3c0P p3c0

        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.

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

        @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 1 Reply Last reply
        0
        • 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