在QML GridView中移动项

在QML GridView中移动项,gridview,drag-and-drop,qml,qt5,qtquick2,Gridview,Drag And Drop,Qml,Qt5,Qtquick2,我有以下关于GridView的代码。里面的矩形是可拖动的。当我在GridView中拖放某个矩形时,拖动的矩形将替换从drop zone中拖放的矩形,但也会替换之间的所有其他矩形(在拖动和拖放之间具有索引)重新排列其位置。 是否可以使拖动的项目仅与放置在拖放区域上的项目交换位置 import QtQml.Models 2.2 import QtQuick 2.3 import QtQuick.Window 2.2 Window { visible: true width: 360

我有以下关于GridView的代码。里面的矩形是可拖动的。当我在GridView中拖放某个矩形时,拖动的矩形将替换从drop zone中拖放的矩形,但也会替换之间的所有其他矩形(在拖动和拖放之间具有索引)重新排列其位置。 是否可以使拖动的项目仅与放置在拖放区域上的项目交换位置

import QtQml.Models 2.2
import QtQuick 2.3
import QtQuick.Window 2.2

Window {
    visible: true
    width: 360
    height: 360

    signal changePosition

    GridView {
        id: root
        width: 320
        height: 480
        cellWidth: 80
        cellHeight: 80

        property int lastChangedIndex: -1
        property int xAxis: 0
        property int yAxis: 0

        displaced: Transition {
            NumberAnimation {
                properties: "x,y"
                easing.type: Easing.OutQuad
            }
        }

        model: DelegateModel {
            id: visualModel
            model: ListModel {
                id: colorModel

                ListElement {
                    color: "blue"
                    itemNumber: "0"
                }
                ListElement {
                    color: "green"
                    itemNumber: "1"
                }
                ListElement {
                    color: "red"
                    itemNumber: "2"
                }
                ListElement {
                    color: "yellow"
                    itemNumber: "3"
                }
                ListElement {
                    color: "orange"
                    itemNumber: "4"
                }
                ListElement {
                    color: "purple"
                    itemNumber: "5"
                }
                ListElement {
                    color: "cyan"
                    itemNumber: "6"
                }
                ListElement {
                    color: "magenta"
                    itemNumber: "7"
                }
            }

            delegate: MouseArea {
                id: delegateRoot

                property bool held: false
                property int visualIndex: DelegateModel.itemsIndex

                width: 80
                height: 80

                drag.target: held ? icon : undefined

                onPressAndHold: {
                    held = true
                    icon.opacity = 0.5
                }
                onReleased: {
                    if (held === true) {
                        held = false
                        icon.opacity = 1
                        icon.Drag.drop()
                    } else {
                        //action on release
                    }
                }

                Rectangle {
                    id: icon
                    width: 50
                    height: 50
                    anchors {
                        horizontalCenter: parent.horizontalCenter
                        verticalCenter: parent.verticalCenter
                    }
                    color: model.color
                    radius: 3

                    Text {
                        anchors.centerIn: parent
                        text: model.itemNumber
                    }

                    Drag.active: delegateRoot.drag.active
                    Drag.source: delegateRoot
                    Drag.hotSpot.x: 36
                    Drag.hotSpot.y: 36

                    states: [
                        State {
                            when: icon.Drag.active

                            ParentChange {
                                target: icon
                                parent: root
                            }

                            AnchorChanges {
                                target: icon
                                anchors.horizontalCenter: undefined
                                anchors.verticalCenter: undefined
                            }
                        }
                    ]
                }

                DropArea {
                    id: dropArea

                    anchors {
                        fill: parent
                        margins: 15
                    }

                    signal trigger

                    Timer {
                        id: dropZoneTimer
                        interval: 1000
                        onTriggered: {
                            dropArea.trigger()
                        }
                    }
                    onTrigger: {
                        visualModel.items.move(drag.source.visualIndex,
                                               delegateRoot.visualIndex)
                        root.lastChangedIndex = delegateRoot.visualIndex
                    }

                    onEntered: {
                        if (drag.source.visualIndex !== delegateRoot.visualIndex) {
                            dropZoneTimer.start()
                        }
                    }
                    onExited: {
                        dropZoneTimer.stop()
                        root.lastChangedIndex = -1
                    }
                    onDropped: {
                        if (root.lastChangedIndex !== delegateRoot.visualIndex) {
                            visualModel.items.move(drag.source.visualIndex,
                                                   delegateRoot.visualIndex)
                        }
                    }
                }
            }
        }
    }
}

我可能会这样做,即交换模型项的值,而不是实际移动它们:


这假设
itemsIndex
属性(通过
visualIndex
)的使用是正确的。

我可能会这样做的方式是交换模型项的值,而不是实际移动它们:


这假定
itemsIndex
属性(通过
visualIndex
)的使用是正确的。

无法访问“DelegateModel”无法访问“DelegateModel”
import QtQml.Models 2.2
import QtQuick 2.3
import QtQuick.Window 2.2

Window {
    visible: true
    width: 360
    height: 360

    GridView {
        id: root
        width: 320
        height: 480
        cellWidth: 80
        cellHeight: 80

        displaced: Transition {
            NumberAnimation {
                properties: "x,y"
                easing.type: Easing.OutQuad
            }
        }

        model: DelegateModel {
            id: visualModel
            model: ListModel {
                id: colorModel

                ListElement {
                    color: "blue"
                    itemNumber: "0"
                }
                ListElement {
                    color: "green"
                    itemNumber: "1"
                }
                ListElement {
                    color: "red"
                    itemNumber: "2"
                }
                ListElement {
                    color: "yellow"
                    itemNumber: "3"
                }
                ListElement {
                    color: "orange"
                    itemNumber: "4"
                }
                ListElement {
                    color: "purple"
                    itemNumber: "5"
                }
                ListElement {
                    color: "cyan"
                    itemNumber: "6"
                }
                ListElement {
                    color: "magenta"
                    itemNumber: "7"
                }
            }

            delegate: MouseArea {
                id: delegateRoot

                property bool held: false
                property int visualIndex: DelegateModel.itemsIndex

                width: 80
                height: 80

                drag.target: held ? icon : undefined

                onPressAndHold: {
                    held = true
                    icon.opacity = 0.5
                }
                onReleased: {
                    if (held === true) {
                        held = false
                        icon.opacity = 1
                        icon.Drag.drop()
                    } else {
                        //action on release
                    }
                }

                Rectangle {
                    id: icon
                    width: 50
                    height: 50
                    anchors {
                        horizontalCenter: parent.horizontalCenter
                        verticalCenter: parent.verticalCenter
                    }
                    color: model.color
                    radius: 3

                    Text {
                        anchors.centerIn: parent
                        text: model.itemNumber
                    }

                    Drag.active: delegateRoot.drag.active
                    Drag.source: delegateRoot
                    Drag.hotSpot.x: 36
                    Drag.hotSpot.y: 36

                    states: [
                        State {
                            when: icon.Drag.active

                            ParentChange {
                                target: icon
                                parent: root
                            }

                            AnchorChanges {
                                target: icon
                                anchors.horizontalCenter: undefined
                                anchors.verticalCenter: undefined
                            }
                        }
                    ]
                }

                DropArea {
                    id: dropArea

                    anchors {
                        fill: parent
                        margins: 15
                    }

                    onDropped: {
                        var sourceColor = colorModel.get(drag.source.visualIndex).color;
                        var sourceNumber = colorModel.get(drag.source.visualIndex).itemNumber;

                        var targetColor = colorModel.get(delegateRoot.visualIndex).color;
                        var targetNumber = colorModel.get(delegateRoot.visualIndex).itemNumber;
                        colorModel.setProperty(drag.source.visualIndex, "color", targetColor);
                        colorModel.setProperty(drag.source.visualIndex, "itemNumber", targetNumber);
                        colorModel.setProperty(delegateRoot.visualIndex, "color", sourceColor);
                        colorModel.setProperty(delegateRoot.visualIndex, "itemNumber", sourceNumber);
                    }
                }
            }
        }
    }
}