繁体   English   中英

在QML GridView中移动项目

[英]Moving item in QML GridView

我有下面的代码与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)
                        }
                    }
                }
            }
        }
    }
}

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

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

在此处输入图片说明

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM