[Solved] How to take a Print in QML?
-
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. -
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 aQImage
. Later you can send it to C++ side using signal/slot or by calling aQ_INVOKABLE
function. Then use QPrinter to print that image. -
@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 aQImage
. Later you can send it to C++ side using signal/slot or by calling aQ_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*/); } }
-
@IT-MAN-2015 As said earlier use
grabToImage
to grab a snapshot of theItem
i.e in your caseWebView
. Then its result will give youQImage
and then send it to C++. So instead of(QString url)
as argument useQVariant
and convert it toQImage
. 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); } }
-
@p3c0 said:
@IT-MAN-2015 As said earlier use
grabToImage
to grab a snapshot of theItem
i.e in your caseWebView
. Then its result will give youQImage
and then send it to C++. So instead of(QString url)
as argument useQVariant
and convert it toQImage
. 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(); } }
-
@IT-MAN-2015 Not need of
QVariant
pointer. It is implicily shared. Afterwards useqvariant_cast
to cast it toQImage
and then as usual of printing. Sovoid pr::print(QVariant data) { //note: it sends a complete image and not just url QImage img = qvariant_cast<QImage>(data); }
-
@p3c0 said:
@IT-MAN-2015 Not need of
QVariant
pointer. It is implicily shared. Afterwards useqvariant_cast
to cast it toQImage
and then as usual of printing. Sovoid 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(); } }
-
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.
-
@IT-MAN-2015 do
#include <QVariant>
-
@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.
-
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.
-
@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(); }
-
@IT-MAN-2015 Thanks for sharing :)
-