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. Share list model between two gridview
Forum Updated to NodeBB v4.3 + New Features

Share list model between two gridview

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
10 Posts 2 Posters 1.2k 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.
  • deleted57D Offline
    deleted57D Offline
    deleted57
    wrote on last edited by
    #1

    I need to share a model list of items between two gridview because I need to move items between the two controls using drag and drop. The obvious solution is to use Package but in my case I have the problem the GridView show an empty space where an items should be also if the item is placed on the other view. A screen shot will crarify the problem. As you can see I add the block by disposing in the two view even and odd but this create the columns you can see. Someone know hwo to make the block to appear in the view in the "normal" order without the spaces?

    alt text

    Follow the example code:

    GridView {
        id: grid1
        cellWidth: 80
        cellHeight: 80
        model: visualDelegateModel.parts.grid1
    }
    
    GridView {
        id: grid2
        cellWidth: 80
        cellHeight: 80
        model: visualDelegateModel.parts.grid2
    }
    
    ListModel {
        id: blocksListModel
        ListElement { color: "blue" }
        ListElement { color: "green" }
        ListElement { color: "red" }
        ListElement { color: "yellow" }
        ListElement { color: "orange" }
        ListElement { color: "purple" }
        ListElement { color: "cyan" }
        ListElement { color: "magenta" }
        ListElement { color: "chartreuse" }
        ListElement { color: "aquamarine" }
        ListElement { color: "indigo" }
        ListElement { color: "black" }
        ListElement { color: "lightsteelblue" }
        ListElement { color: "violet" }
        ListElement { color: "grey" }
        ListElement { color: "springgreen" }
        ListElement { color: "salmon" }
        ListElement { color: "blanchedalmond" }
        ListElement { color: "forestgreen" }
        ListElement { color: "pink" }
        ListElement { color: "navy" }
        ListElement { color: "goldenrod" }
        ListElement { color: "crimson" }
        ListElement { color: "teal" }
    }
    
    DelegateModel {
        id: visualDelegateModel
        delegate: Block {}
        model: blocksListModel
    }
    

    And this is the Block delegate:

    Package {
        id: packageRoot
    
        Item { id: grid1Delegate; Package.name: "grid1"}
        Item { id: grid2Delegate; Package.name: "grid2" }
    
        Rectangle {
            id: block
            width: 72; height: 72
            anchors {
                horizontalCenter: parent.horizontalCenter;
                verticalCenter: parent.verticalCenter
            }
            color: model.color
            radius: 3
    
            state: (index % 2) ? "grid1" : "grid2"
    
            states: [
                State {
                    name: "grid1"
                    ParentChange { target: block; parent: grid1Delegate }
                },
                State {
                    name: "grid2"
                    ParentChange { target: block; parent: grid2Delegate }
                }
            ]
        }
    }
    
    DiracsbracketD 1 Reply Last reply
    0
    • deleted57D deleted57

      I need to share a model list of items between two gridview because I need to move items between the two controls using drag and drop. The obvious solution is to use Package but in my case I have the problem the GridView show an empty space where an items should be also if the item is placed on the other view. A screen shot will crarify the problem. As you can see I add the block by disposing in the two view even and odd but this create the columns you can see. Someone know hwo to make the block to appear in the view in the "normal" order without the spaces?

      alt text

      Follow the example code:

      GridView {
          id: grid1
          cellWidth: 80
          cellHeight: 80
          model: visualDelegateModel.parts.grid1
      }
      
      GridView {
          id: grid2
          cellWidth: 80
          cellHeight: 80
          model: visualDelegateModel.parts.grid2
      }
      
      ListModel {
          id: blocksListModel
          ListElement { color: "blue" }
          ListElement { color: "green" }
          ListElement { color: "red" }
          ListElement { color: "yellow" }
          ListElement { color: "orange" }
          ListElement { color: "purple" }
          ListElement { color: "cyan" }
          ListElement { color: "magenta" }
          ListElement { color: "chartreuse" }
          ListElement { color: "aquamarine" }
          ListElement { color: "indigo" }
          ListElement { color: "black" }
          ListElement { color: "lightsteelblue" }
          ListElement { color: "violet" }
          ListElement { color: "grey" }
          ListElement { color: "springgreen" }
          ListElement { color: "salmon" }
          ListElement { color: "blanchedalmond" }
          ListElement { color: "forestgreen" }
          ListElement { color: "pink" }
          ListElement { color: "navy" }
          ListElement { color: "goldenrod" }
          ListElement { color: "crimson" }
          ListElement { color: "teal" }
      }
      
      DelegateModel {
          id: visualDelegateModel
          delegate: Block {}
          model: blocksListModel
      }
      

      And this is the Block delegate:

      Package {
          id: packageRoot
      
          Item { id: grid1Delegate; Package.name: "grid1"}
          Item { id: grid2Delegate; Package.name: "grid2" }
      
          Rectangle {
              id: block
              width: 72; height: 72
              anchors {
                  horizontalCenter: parent.horizontalCenter;
                  verticalCenter: parent.verticalCenter
              }
              color: model.color
              radius: 3
      
              state: (index % 2) ? "grid1" : "grid2"
      
              states: [
                  State {
                      name: "grid1"
                      ParentChange { target: block; parent: grid1Delegate }
                  },
                  State {
                      name: "grid2"
                      ParentChange { target: block; parent: grid2Delegate }
                  }
              ]
          }
      }
      
      DiracsbracketD Offline
      DiracsbracketD Offline
      Diracsbracket
      wrote on last edited by Diracsbracket
      #2

      @Suppaman
      Your problem is very easy to solve with a proxy model.
      https://github.com/oKcerG/SortFilterProxyModel

      I wouldn't know how to solve your problem using the Package approach though. It would seem that there must be a simple solution to it, but I'm not very familiar with the Package construct.

      This proxy model library above is super easy to install and use, and it solves your problem like this:

      To each element in your ListModel, add an additional property e.g. grid which identifies your grid, 0 or 1, e.g.

      ListModel {
          id: blocksListModel
          ListElement { color: "blue"; grid: 0 }
          ListElement { color: "green"; grid: 1 }
          ...
      }
      

      Then, define each of your GridViews as follows:

        GridView {
                  width: parent.width
                  height: parent.height/2
                  id: grid1
                  cellWidth: 80
                  cellHeight: 80
      
                  model: SortFilterProxyModel  {
                      sourceModel: blocksListModel
                      filters: ValueFilter {
                          roleName: "grid"
                          value: 0
                      }
                  }
      
                  delegate: blockComp
              }
      
        GridView {
                  width: parent.width
                  height: parent.height/2
                  id: grid2
                  cellWidth: 80
                  cellHeight: 80
      
                  model: SortFilterProxyModel  {
                      sourceModel: blocksListModel
                      filters: ValueFilter {
                          roleName: "grid"
                          value: 1
                      }
                  }
      
                  delegate: blockComp
              }
      

      where blockComp is your delegate:

          Component {
              id: blockComp
              Item {
                  Rectangle {
                      id: block
                      width: 72
                      height: 72
                      x: 4
                      y: 4
                      color: model.color
                      radius: 3
      
                      MouseArea {
                          anchors.fill: parent
                          onClicked: {
                              model.grid = !model.grid
                          }
                      }
                  }
              }
      

      As you can see, in the example above, clicking the delegate will move it to the other grid. In your case, you will do it by drag/drop.

      P.S. the above trick model.grid = !model.grid will generate warnings, because grid is interpreted as Number and not a Bool, but that's easy to solve.

      1 Reply Last reply
      0
      • deleted57D Offline
        deleted57D Offline
        deleted57
        wrote on last edited by
        #3

        Hi

        At first thank you for your reply. Unfortunately your solution can not be applied in my case since I need to use a DelegateModel for move the intem inside the gridview and, just verified, SortFilterProxyModel can't work cause DelegateModel have both model and delegate and SortFilterProxyModel filter model only.

        DiracsbracketD 1 Reply Last reply
        0
        • deleted57D deleted57

          Hi

          At first thank you for your reply. Unfortunately your solution can not be applied in my case since I need to use a DelegateModel for move the intem inside the gridview and, just verified, SortFilterProxyModel can't work cause DelegateModel have both model and delegate and SortFilterProxyModel filter model only.

          DiracsbracketD Offline
          DiracsbracketD Offline
          Diracsbracket
          wrote on last edited by Diracsbracket
          #4

          @Suppaman
          You're right. I didn't think about also moving the delegate.
          In that case, maybe you can use two ObjectModel, one per GridView and then dynamically move a model item from one model to the other? I.e. when you drop it onto the other GridView, remove it from the parent model, then dynamically create a copy of it to add to the other model.

          But, hopefully, someone will come up with a way to make the Package method work...

          1 Reply Last reply
          0
          • deleted57D Offline
            deleted57D Offline
            deleted57
            wrote on last edited by
            #5

            Hi

            Yes, the solution you proposed is the obvious way to proceed but the project I have in mind is more complicated unfortunately. I'll try to explain as my best. Do you know the Qt example draganddrop provided with Qt Creator? I guess yes, but in case this example software show a way to fill a GridView control with colored blocks, like in the picture I posted here. If you drag one of these block and moving around the control all other blocks under the corrent draggred move away and leave the space for drop the block. In this way you can order the block as you prefer. I want to make a project containing two GridView and want to move the blocks between these two controls but keeping this "effect" or reordering in both gridview with the same dragged block. The problem is if I drag a block and move on the other gridview I don't have the "effect" of blocks moving away cause the dragged block is in the range of the origin gridview. Adding the block to the target gridview and removing the original dragged will have a consequence that I lost my current dragged block cause removing from the module delete the object. As everything in programming there are various solution to each problem but I'm looking for the correct way to reach such result and still didn't find. Hope to explained well the project I have in mind...

            DiracsbracketD 1 Reply Last reply
            0
            • deleted57D deleted57

              Hi

              Yes, the solution you proposed is the obvious way to proceed but the project I have in mind is more complicated unfortunately. I'll try to explain as my best. Do you know the Qt example draganddrop provided with Qt Creator? I guess yes, but in case this example software show a way to fill a GridView control with colored blocks, like in the picture I posted here. If you drag one of these block and moving around the control all other blocks under the corrent draggred move away and leave the space for drop the block. In this way you can order the block as you prefer. I want to make a project containing two GridView and want to move the blocks between these two controls but keeping this "effect" or reordering in both gridview with the same dragged block. The problem is if I drag a block and move on the other gridview I don't have the "effect" of blocks moving away cause the dragged block is in the range of the origin gridview. Adding the block to the target gridview and removing the original dragged will have a consequence that I lost my current dragged block cause removing from the module delete the object. As everything in programming there are various solution to each problem but I'm looking for the correct way to reach such result and still didn't find. Hope to explained well the project I have in mind...

              DiracsbracketD Offline
              DiracsbracketD Offline
              Diracsbracket
              wrote on last edited by Diracsbracket
              #6

              @Suppaman
              In the example below, I didn't have the time to get the details right, but it shows you that the approach outlined previously works.
              I just took the original drag and drop example and split it into two GridView, each with their own DelegateModel.

              0_1536298004618_dragdrop.gif

              So you could try yourself. The implementation details to make it work correctly are up to you. Good luck.

              1 Reply Last reply
              1
              • deleted57D Offline
                deleted57D Offline
                deleted57
                wrote on last edited by deleted57
                #7

                Interesting. With the "approach outlined previously" you mean using SortFilterProxyModel? Because the main problem is the empry space that happear under the dragged block is basically the "invisible" part of the dragged block item (the MouseArea in this case) moved in position under the point where the deagged block is currently. However moving in another view, as the case, the same item is not present cause is still on the original view list. In your example how did you managed to create the empty space under the dragged block without destory and recreate the blok item as effect to move it between the two view list?

                DiracsbracketD 1 Reply Last reply
                0
                • deleted57D deleted57

                  Interesting. With the "approach outlined previously" you mean using SortFilterProxyModel? Because the main problem is the empry space that happear under the dragged block is basically the "invisible" part of the dragged block item (the MouseArea in this case) moved in position under the point where the deagged block is currently. However moving in another view, as the case, the same item is not present cause is still on the original view list. In your example how did you managed to create the empty space under the dragged block without destory and recreate the blok item as effect to move it between the two view list?

                  DiracsbracketD Offline
                  DiracsbracketD Offline
                  Diracsbracket
                  wrote on last edited by Diracsbracket
                  #8

                  @Suppaman said in Share list model between two gridview:

                  you mean using SortFilterProxyModel?

                  No. I just use the exact same approach as in the Qt Drag and Drop example, the GridView part.

                  how did you managed to create the empty space under the dragged block

                  I used a transparent dummy which I added to the model of the 2nd grid and which is made to track the movement of the dragged tile until the other one is dropped onto it. at which point the dummy is destroyed. As you can see from the animation above, I didn't get the tracking part quite right yet. But that was not the point of the exercise to me :-). At least, you get the idea.

                  Also, I don't really like the way the empty square in the first grid remains until the drop is complete. I rather would have the grid collapse immediately as soon as the tile is undocked. Maybe I'll try again later.

                  I still hope though that someone can come up with a better solution...

                  1 Reply Last reply
                  0
                  • deleted57D Offline
                    deleted57D Offline
                    deleted57
                    wrote on last edited by
                    #9

                    Hi
                    I really thank you for your time. About issue regarding the problem of grid collapse immediately as soon as the tile is undocked don't worry, I fixed by tracking the exit from DropArea and move the empy item of the last position of the grid. Currently I'm making some test by set the dragged item to the inPersistedItems group that allow to remove the item from the model without automatically destory it, hope to reach some result following this way...

                    DiracsbracketD 1 Reply Last reply
                    1
                    • deleted57D deleted57

                      Hi
                      I really thank you for your time. About issue regarding the problem of grid collapse immediately as soon as the tile is undocked don't worry, I fixed by tracking the exit from DropArea and move the empy item of the last position of the grid. Currently I'm making some test by set the dragged item to the inPersistedItems group that allow to remove the item from the model without automatically destory it, hope to reach some result following this way...

                      DiracsbracketD Offline
                      DiracsbracketD Offline
                      Diracsbracket
                      wrote on last edited by
                      #10

                      @Suppaman said in Share list model between two gridview:

                      hope to reach some result following this way...

                      I hope you will post a snapshot of your result. It would be nice to see.

                      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