Unsolved Share list model between two gridview
-
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?
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 } } ] } }
-
@Suppaman
Your problem is very easy to solve with a proxy model.
https://github.com/oKcerG/SortFilterProxyModelI 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 thePackage
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, becausegrid
is interpreted asNumber
and not aBool
, but that's easy to solve. -
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.
-
@Suppaman
You're right. I didn't think about also moving the delegate.
In that case, maybe you can use twoObjectModel
, one perGridView
and then dynamically move a model item from one model to the other? I.e. when you drop it onto the otherGridView
, 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... -
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...
-
@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 twoGridView
, each with their ownDelegateModel
.So you could try yourself. The implementation details to make it work correctly are up to you. Good luck.
-
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?
-
@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...
-
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... -
@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.