QML listview delegate item as QQuickItem
-
wrote on 27 May 2016, 06:22 last edited by haris123
I manged to get it work using the above code with below modification, but the issue is the image saved is small as table cell.
for(var i=0; i<table_list_view.contentItem.children.length; i++) { for(var j=0; j<table_list_view.contentItem.children[i].children.length; j++){ for(var k=0; k<table_list_view.contentItem.children[i].children[j].children.length; k++){ for(var l=0; l<table_list_view.contentItem.children[i].children[j].children[k].children.length; l++){ console.log(i+" "+j+" "+k+" "+l+" "+table_list_view.contentItem.children[i].children[j].children[k].children[l]) if(k===1&&l===0) //filter image component only login.save(table_list_view.contentItem.children[i].children[j].children[k].children[l]); } } } }
c++ code,
void Login::save( QQuickItem *item) { auto grabResult = item->grabToImage(); connect(grabResult.data(), &QQuickItemGrabResult::ready, [=]() { static int c=0; c++; QString fileName = "C:/Users/vapplica/Desktop/"+QString::number(c)+".png"; qDebug()<<"Saving image.."+fileName; grabResult->saveToFile(fileName); QImage img = grabResult->image();// gives the QImage associated if you want to use it directly in the program int p=0; });
}
My ultimate purpose is, load network image in qml asynchronously and save it to disk. But I think it wont work like, save image with original resolution by extracting it from listview delegate. Do you have any suggestion.
-
I manged to get it work using the above code with below modification, but the issue is the image saved is small as table cell.
for(var i=0; i<table_list_view.contentItem.children.length; i++) { for(var j=0; j<table_list_view.contentItem.children[i].children.length; j++){ for(var k=0; k<table_list_view.contentItem.children[i].children[j].children.length; k++){ for(var l=0; l<table_list_view.contentItem.children[i].children[j].children[k].children.length; l++){ console.log(i+" "+j+" "+k+" "+l+" "+table_list_view.contentItem.children[i].children[j].children[k].children[l]) if(k===1&&l===0) //filter image component only login.save(table_list_view.contentItem.children[i].children[j].children[k].children[l]); } } } }
c++ code,
void Login::save( QQuickItem *item) { auto grabResult = item->grabToImage(); connect(grabResult.data(), &QQuickItemGrabResult::ready, [=]() { static int c=0; c++; QString fileName = "C:/Users/vapplica/Desktop/"+QString::number(c)+".png"; qDebug()<<"Saving image.."+fileName; grabResult->saveToFile(fileName); QImage img = grabResult->image();// gives the QImage associated if you want to use it directly in the program int p=0; });
}
My ultimate purpose is, load network image in qml asynchronously and save it to disk. But I think it wont work like, save image with original resolution by extracting it from listview delegate. Do you have any suggestion.
-
wrote on 27 May 2016, 10:42 last edited by haris123
I tried that, but when I give targetSize to it's orginal image resolution it's giving the output png with expected resolution where as the image portion is scaled to different.
Another thing I have tried is
item->resetHeight(); item->resetWidth();
inside the function
void Login::save( QQuickItem *item),
where as this changes the image object showing in qml list view, as both uses same object. And I coud'nt find a way to deep copy of QQuickItem .
-
I tried that, but when I give targetSize to it's orginal image resolution it's giving the output png with expected resolution where as the image portion is scaled to different.
Another thing I have tried is
item->resetHeight(); item->resetWidth();
inside the function
void Login::save( QQuickItem *item),
where as this changes the image object showing in qml list view, as both uses same object. And I coud'nt find a way to deep copy of QQuickItem .
@haris123 Can you confirm if its the same behavior as above with the following example code ?
import QtQuick 2.6 import QtQuick.Controls 1.4 Rectangle { id: rect width: 200 height: 200 Image { id: img anchors.fill: parent source: "http://r0k.us/graphics/kodak/kodak/kodim03.png" } Button { anchors.bottom: parent.bottom text: "Grab" onClicked: { img.grabToImage(function(result) { result.saveToFile("myimage.png"); }, Qt.size(768, 512)); } } }
-
wrote on 27 May 2016, 11:38 last edited by haris123
Thanks for the replay,
The above code works fine here also, but when I used the same in list view gave scaled output.
import QtQuick 2.3 import QtQuick.Window 2.2 import QtQuick.Controls 1.4 Window { property int count: 0 visible: true width : 900 height: 900 Rectangle{ width: parent.width height:parent.height color: "#000000" Component { id: appDelegate; Item { width:parent.width; height:50; Row{ id:table_row Rectangle { id:cam_cln width:200; height:50; color: "#88FF3333" border.width: 1; border.color: "white" Text{ id: cam_txt anchors.centerIn: parent text: cam; //font.bold : true //font.pointSize: 9 color: "white" } MouseArea{ anchors.fill: parent onClicked: { table_list_view.currentIndex=index; } } } Rectangle { id:img_cln width:200; height:50; color: "#88333333" border.width: 1; border.color: "white" Image { id: myIcon; width:200; height:50; anchors.horizontalCenter: parent.horizontalCenter; source: icon; fillMode: Image.PreserveAspectFit cache : true; asynchronous: true; } MouseArea{ anchors.fill: parent onClicked: { table_list_view.currentIndex=index; } } } } } } ListView { id: table_list_view highlightMoveVelocity :1000 // objectName: "gridObject" anchors.fill: parent cacheBuffer:50 clip: true; focus: true model: appModel highlight: Rectangle { color: "#BB333333"; radius: 3 } delegate: appDelegate flickableDirection: Flickable.VerticalFlick flickableChildren: MouseArea { anchors.fill: parent onClicked:{ } } } ListModel { id: appModel } Component.onCompleted: { appModel.append({ cam:"Image1",icon: "http://www.gstatic.com/webp/gallery/4.jpg" }) appModel.append({ cam:"Image2",icon: "http://www.gstatic.com/webp/gallery/2.jpg" }) appModel.append({ cam:"Image3",icon: "http://www.gstatic.com/webp/gallery/3.jpg" }) appModel.append({ cam:"Image3",icon: "http://r0k.us/graphics/kodak/kodak/kodim03.png" }) } } Button { anchors.bottom: parent.bottom text: "Grab" onClicked: { for(var i=0; i<table_list_view.contentItem.children.length; i++) { for(var j=0; j<table_list_view.contentItem.children[i].children.length; j++){ for(var k=0; k<table_list_view.contentItem.children[i].children[j].children.length; k++){ for(var l=0; l<table_list_view.contentItem.children[i].children[j].children[k].children.length; l++){ console.log(i+" "+j+" "+k+" "+l+" "+table_list_view.contentItem.children[i].children[j].children[k].children[l]) if(k===1&&l===0){ table_list_view.contentItem.children[i].children[j].children[k].children[l].grabToImage(function(result) { var fielName = "C:/Users/haris/Desktop/"+count+".png" result.saveToFile(fielName); count++; }, Qt.size(768, 512)); } } } } } }
}
}
-
Thanks for the replay,
The above code works fine here also, but when I used the same in list view gave scaled output.
import QtQuick 2.3 import QtQuick.Window 2.2 import QtQuick.Controls 1.4 Window { property int count: 0 visible: true width : 900 height: 900 Rectangle{ width: parent.width height:parent.height color: "#000000" Component { id: appDelegate; Item { width:parent.width; height:50; Row{ id:table_row Rectangle { id:cam_cln width:200; height:50; color: "#88FF3333" border.width: 1; border.color: "white" Text{ id: cam_txt anchors.centerIn: parent text: cam; //font.bold : true //font.pointSize: 9 color: "white" } MouseArea{ anchors.fill: parent onClicked: { table_list_view.currentIndex=index; } } } Rectangle { id:img_cln width:200; height:50; color: "#88333333" border.width: 1; border.color: "white" Image { id: myIcon; width:200; height:50; anchors.horizontalCenter: parent.horizontalCenter; source: icon; fillMode: Image.PreserveAspectFit cache : true; asynchronous: true; } MouseArea{ anchors.fill: parent onClicked: { table_list_view.currentIndex=index; } } } } } } ListView { id: table_list_view highlightMoveVelocity :1000 // objectName: "gridObject" anchors.fill: parent cacheBuffer:50 clip: true; focus: true model: appModel highlight: Rectangle { color: "#BB333333"; radius: 3 } delegate: appDelegate flickableDirection: Flickable.VerticalFlick flickableChildren: MouseArea { anchors.fill: parent onClicked:{ } } } ListModel { id: appModel } Component.onCompleted: { appModel.append({ cam:"Image1",icon: "http://www.gstatic.com/webp/gallery/4.jpg" }) appModel.append({ cam:"Image2",icon: "http://www.gstatic.com/webp/gallery/2.jpg" }) appModel.append({ cam:"Image3",icon: "http://www.gstatic.com/webp/gallery/3.jpg" }) appModel.append({ cam:"Image3",icon: "http://r0k.us/graphics/kodak/kodak/kodim03.png" }) } } Button { anchors.bottom: parent.bottom text: "Grab" onClicked: { for(var i=0; i<table_list_view.contentItem.children.length; i++) { for(var j=0; j<table_list_view.contentItem.children[i].children.length; j++){ for(var k=0; k<table_list_view.contentItem.children[i].children[j].children.length; k++){ for(var l=0; l<table_list_view.contentItem.children[i].children[j].children[k].children.length; l++){ console.log(i+" "+j+" "+k+" "+l+" "+table_list_view.contentItem.children[i].children[j].children[k].children[l]) if(k===1&&l===0){ table_list_view.contentItem.children[i].children[j].children[k].children[l].grabToImage(function(result) { var fielName = "C:/Users/haris/Desktop/"+count+".png" result.saveToFile(fielName); count++; }, Qt.size(768, 512)); } } } } } }
}
}
@haris123 Scaling it seems is because of
fillMode: Image.PreserveAspectFit
-
wrote on 27 May 2016, 11:58 last edited by
You are right, now it's working as expected. The main issue solved, I can avoid the aspect fit, let the table in filled mode, but did you noticed that the last image wont saved, is that behavior there?.
-
You are right, now it's working as expected. The main issue solved, I can avoid the aspect fit, let the table in filled mode, but did you noticed that the last image wont saved, is that behavior there?.
@haris123 No. All 4 were saved. But I noticed you have mistakenly added same role values for last 2 items.
cam:"Image3"
-
wrote on 27 May 2016, 12:12 last edited by
Thanks for noticing, I have rebuild and run again, now it's works fine, thanks once again, I really appreciate your help.
-
Thanks for noticing, I have rebuild and run again, now it's works fine, thanks once again, I really appreciate your help.
@haris123 You're Welcome,
Btw. if your aim is to capture all the images at once you can avoid the cumbersome task of iterating children. You can use signal and slots mechanim here too.
For eg.//Inside the Window declare a signal Window { id: win ... signal capture; ... //Inside the Image delegate use Connections to connect to the signal ... Image { id: myIcon; ... Connections { target: win onCapture: { myIcon.grabToImage(function(result) { result.saveToFile("C:/Users/vapplica/Desktop/"+index+".png"); }, Qt.size(768, 512)); } } } //Fire the signal Button { ... text: "Grab" onClicked: { win.capture() } }
Also you can directly access Image source size which will be helpful for saving the images. So you can replace
Qt.size(768, 512)
withQt.size(myIcon.sourceSize.width, myIcon.sourceSize.height)
Here is the doc for Connections.
-
wrote on 27 May 2016, 13:45 last edited by
Not all the image, only selected image by the user, actually in my original application there is third delegate item
tickbox
using it user can select the image to download. Any way thanks for informing me the new method.
16/17