首页 文章

在QML GridView中移动项目

提问于
浏览
0

我有以下代码与GridView . 里面的矩形是可拖动的 . 当我在GridView中拖放一些矩形时,拖动的矩形会替换掉落区域中的一个矩形,但也会替换它们之间的所有其他矩形(它们之间有拖动和拖放之间的索引)重新排序它们的位置 . 是否可以使拖动的项目仅与放置在放置区域的项目交换位置?

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

1 回答

  • 2

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

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

    enter image description here

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

相关问题