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. QML listview delegate item as QQuickItem
Forum Updated to NodeBB v4.3 + New Features

QML listview delegate item as QQuickItem

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
17 Posts 2 Posters 6.6k Views 1 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.
  • H Offline
    H Offline
    haris123
    wrote on last edited by
    #1

    I have list view with delegate items with two component Text and Image

    The listview

    ListView {
        id: table_list_view
        anchors.fill: parent
        model: appModel
        highlight:  Rectangle { color: "#BB333333"; radius: 3 }
        delegate: appDelegate
    }
    

    And the delegate is like,

     Component {
            id: appDelegate;
    
            Item {
                width:parent.width;
                height:50;
               Row{
                   id:table_row
    
                Rectangle {
                     id:title_cln
                     width:200;
                     height:50;
                     color: "#88FF3333"
                     border.width: 1;
                     border.color: "white"
    
                     Text{
                         id: title_txt
                         anchors.centerIn: parent
                         text: title;
                         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;
                         }
                     }
                   }
        }
        }
        }
    

    And the list model

    ListModel {
            id: appModel
    
        }
    

    I am filling like

     Component.onCompleted: {
           appModel.append({ title:"Image1",icon: "http://www.gstatic.com/webp/gallery/4.jpg" })
           appModel.append({ title:"Image2",icon: "http://www.gstatic.com/webp/gallery/2.jpg" })
           appModel.append({ title:"Image3",icon: "http://www.gstatic.com/webp/gallery/3.jpg" })
    
      }
    

    Now what I need to implement is get each delegate image item as QQuickItem and then pass to c++ for further processing,

    I can get text from the model like,

    for(var i=0;i<appModel.count;i++)
               var text =appModel.get(i).title;
    

    Using the same way how can I get Image component with the id myIcon

    p3c0P 1 Reply Last reply
    0
    • H haris123

      I have list view with delegate items with two component Text and Image

      The listview

      ListView {
          id: table_list_view
          anchors.fill: parent
          model: appModel
          highlight:  Rectangle { color: "#BB333333"; radius: 3 }
          delegate: appDelegate
      }
      

      And the delegate is like,

       Component {
              id: appDelegate;
      
              Item {
                  width:parent.width;
                  height:50;
                 Row{
                     id:table_row
      
                  Rectangle {
                       id:title_cln
                       width:200;
                       height:50;
                       color: "#88FF3333"
                       border.width: 1;
                       border.color: "white"
      
                       Text{
                           id: title_txt
                           anchors.centerIn: parent
                           text: title;
                           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;
                           }
                       }
                     }
          }
          }
          }
      

      And the list model

      ListModel {
              id: appModel
      
          }
      

      I am filling like

       Component.onCompleted: {
             appModel.append({ title:"Image1",icon: "http://www.gstatic.com/webp/gallery/4.jpg" })
             appModel.append({ title:"Image2",icon: "http://www.gstatic.com/webp/gallery/2.jpg" })
             appModel.append({ title:"Image3",icon: "http://www.gstatic.com/webp/gallery/3.jpg" })
      
        }
      

      Now what I need to implement is get each delegate image item as QQuickItem and then pass to c++ for further processing,

      I can get text from the model like,

      for(var i=0;i<appModel.count;i++)
                 var text =appModel.get(i).title;
      

      Using the same way how can I get Image component with the id myIcon

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

      @haris123 You can apply one of the following technique as explained here
      http://forum.qt.io/topic/67493/solved-saving-qml-image-from-c

      157

      1 Reply Last reply
      1
      • H Offline
        H Offline
        haris123
        wrote on last edited by haris123
        #3

        I that case only one item can pass, but my case is I have to pass selected item from a listview.

        p3c0P 1 Reply Last reply
        0
        • H haris123

          I that case only one item can pass, but my case is I have to pass selected item from a listview.

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

          @haris123 @haris123 You can do in following ways:

          • Inside Image you can monitor the Status using its corresponding handler onStatusChanged and when Image.Ready is triggered you call the C++ function passing it the image which I had explained in the earlier post.
          • From C++ use findChild to find the ListView and then access its contentItem property which gives a list of delegates(these are children of content item). Then you can iterate over the children(list of QQuickItems) and call the grabToImage on each. For eg. to get list of items
          QQuickItem *itm =  qvariant_cast<QQuickItem*>(view.rootObject()->findChild<QQuickItem*>("mylist")->property("contentItem"));
          QList<QQuickItem*> list = itm->childItems();
          //Then iterate over this list and call the function. 
          //May be you will need to go in further i.e access children of children
          

          157

          1 Reply Last reply
          0
          • H Offline
            H Offline
            haris123
            wrote on last edited by
            #5

            Hi Thanks for the answer,

            So is there any why to iterate delegate item from QML?

            p3c0P 1 Reply Last reply
            0
            • H haris123

              Hi Thanks for the answer,

              So is there any why to iterate delegate item from QML?

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

              @haris123 Yes it is possible too. The delegates are children of contentItem. Similar to C++ here too you can iterate over its children. A typical code to do this Rectangle as delegate is as follows:

              for(var i=0; i<list.contentItem.children.length; i++) {
                  console.log(list.contentItem.children[i])
              }
              

              This will list all the Rectangle's.

              157

              1 Reply Last reply
              1
              • H Offline
                H Offline
                haris123
                wrote on last edited by haris123
                #7

                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.

                p3c0P 1 Reply Last reply
                0
                • H 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.

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

                  @haris123 What if you specify targetSize as explained here ?

                  157

                  1 Reply Last reply
                  1
                  • H Offline
                    H Offline
                    haris123
                    wrote on last edited by haris123
                    #9

                    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 .

                    p3c0P 1 Reply Last reply
                    0
                    • H 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 .

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

                      @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));
                              }
                          }
                      }
                      
                      

                      157

                      1 Reply Last reply
                      1
                      • H Offline
                        H Offline
                        haris123
                        wrote on last edited by haris123
                        #11

                        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));
                                               }
                                            }
                                        }
                                 }
                              }
                           }
                        

                        }

                        }

                        p3c0P 1 Reply Last reply
                        0
                        • H 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));
                                                 }
                                              }
                                          }
                                   }
                                }
                             }
                          

                          }

                          }

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

                          @haris123 Scaling it seems is because of fillMode: Image.PreserveAspectFit

                          157

                          1 Reply Last reply
                          1
                          • H Offline
                            H Offline
                            haris123
                            wrote on last edited by
                            #13

                            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?.

                            p3c0P 1 Reply Last reply
                            0
                            • H haris123

                              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?.

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

                              @haris123 No. All 4 were saved. But I noticed you have mistakenly added same role values for last 2 items.
                              cam:"Image3"

                              157

                              1 Reply Last reply
                              0
                              • H Offline
                                H Offline
                                haris123
                                wrote on last edited by
                                #15

                                Thanks for noticing, I have rebuild and run again, now it's works fine, thanks once again, I really appreciate your help.

                                p3c0P 1 Reply Last reply
                                0
                                • H haris123

                                  Thanks for noticing, I have rebuild and run again, now it's works fine, thanks once again, I really appreciate your help.

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

                                  @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) with Qt.size(myIcon.sourceSize.width, myIcon.sourceSize.height)

                                  Here is the doc for Connections.

                                  157

                                  1 Reply Last reply
                                  0
                                  • H Offline
                                    H Offline
                                    haris123
                                    wrote on last edited by
                                    #17

                                    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.

                                    1 Reply Last reply
                                    0

                                    • Login

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