Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to retrieve the new ordered list of ListModel inside ListView after drag and drop event

Tags:

qt

qml

qtquick2

I have this simple qml code

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
import QtQml.Models 2.2

ApplicationWindow {
    visible: true
    width: 300
    height: 120
    title: qsTr("Hello World")
    Rectangle {
        anchors.fill: parent;

        ListView{
            id: timeline
            anchors.fill: parent
            orientation: ListView.Horizontal
            model: visualModel
            delegate: timelineDelegate

            moveDisplaced: Transition {
                NumberAnimation{
                    properties: "x,y"
                    duration: 200
                }
            }

            DelegateModel {
                id: visualModel
                model: timelineModel
                delegate: timelineDelegate
            }

            Component {
                id: timelineDelegate


                MouseArea {
                    id: dragArea

                    width: 100; height: 100

                    property bool held: false

                    drag.target: held ? content : undefined
                    drag.axis: Drag.XAxis

                    onPressAndHold: held = true
                    onReleased: {
                        held = false
                        var listOnModel = "{";
                        for(var i = 0; i < timelineModel.count; i++){
                            listOnModel += timelineModel.get(i).colore + ", "
                        }
                        console.log("List: " + listOnModel + "}");
                    }

                    Rectangle {
                        id: content

                        anchors { horizontalCenter: parent.horizontalCenter; verticalCenter: parent.verticalCenter }
                        width: 100
                        height: 100

                        color: colore
                        opacity: dragArea.held ? 0.8 : 1.0

                        Text{
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.horizontalCenter: parent.horizontalCenter
                            text: index
                            font.pixelSize: 20
                        }

                        Drag.active: dragArea.held
                        Drag.source: dragArea
                        Drag.hotSpot.x: width / 2
                        Drag.hotSpot.y: height / 2

                        states: State{
                            when: dragArea.held
                            ParentChange { target: content; parent: timeline }
                            AnchorChanges {
                                target: content
                                anchors { horizontalCenter: undefined; verticalCenter: undefined }
                            }
                        }
                    }

                    DropArea {
                        anchors.fill: parent
                        onEntered: {
                            visualModel.items.move( drag.source.DelegateModel.itemsIndex, dragArea.DelegateModel.itemsIndex);
                        }

                    }
                }
            }

            ListModel {
                id: timelineModel
                // @disable-check M16
                ListElement { colore: "blue" }
                // @disable-check M16
                ListElement { colore: "orange" }
                // @disable-check M16
                ListElement { colore: "green" }
            }
        }
    }
}

Here we have a simple list of colored draggable rectangles. In the center of every rectangle is shown the actual index, that this component has inside the model.

enter image description here

As you can see, after the drop event, the index for every item doesn't change, and the order of the items inside the model is still the same. Is there a way to retrieve the new order of the list after a drag and drop event occurred?

like image 372
Elia Avatar asked Dec 06 '16 10:12

Elia


1 Answers

You don't reorder the ListModel, but the items of your DelegateModel. So you need to use this code instead:

onReleased: {
    held = false
    var listOnModel = "{";
    for(var i = 0; i < visualModel.items.count; i++){
        listOnModel += visualModel.items.get(i).model.colore + ", "
    }
    console.log("List: " + listOnModel + "}");
}
like image 127
derM Avatar answered Oct 23 '22 22:10

derM