在GridView中交换元素 [英] Swap elements in a GridView

查看:65
本文介绍了在GridView中交换元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个QML程序,该程序实质上是一个4x4 GridView,其中填充有编号的矩形。我希望能够:

I'm writing a QML program that is essentially a 4x4 GridView filled with numbered rectangles. I would like to be able to:


  1. 从网格中交换两个元素,拖放

  1. Swap two elements from the grid, dragging and dropping

仅允许直接相邻元素交换

Allow swap only for directly adjacent elements

我当前的问题是只要将一个元素拖到另一个元素上,整个网格就会调整位置,以填充元素原来所在的间隙。有什么方法可以避免这种类型的网格的自动调整行为?

My current problem is that as soon as I drag an element on top of another, the whole grid adjusts positions filling the gap where the element originally was. Is there any way to avoid the auto adjust behavior for that type of grid?

我知道下面的代码可能是导致这种行为的原因,我只是想不通如何正确地更改它。

I'm aware that the piece of code below might be the one responsible for this behavior, I just can't figure out how to change it the propper way.

DropArea {
            anchors { fill: parent; margins: 15 }
            onEntered: {visualModel.items.move(drag.source.visualIndex, delegateRoot.visualIndex)}
        }

完整代码:

import QtQuick 2.0
import QtQml.Models 2.1

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

    displaced: Transition {
        NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad }//Animação anima a transicao dos tiles
    }

    model: DelegateModel {
        id: visualModel
        model: ListModel {
            id: colorModel
            ListElement { color: "lightsteelblue" ; text: "1" }
            ListElement { color: "lightsteelblue" ; text: "2" }
            ListElement { color: "lightsteelblue" ; text: "3" }
            ListElement { color: "lightsteelblue" ; text: "4" }
            ListElement { color: "lightsteelblue" ; text: "5" }
            ListElement { color: "lightsteelblue" ; text: "6" }
            ListElement { color: "lightsteelblue" ; text: "7" }
            ListElement { color: "lightsteelblue" ; text: "8" }
            ListElement { color: "lightsteelblue" ; text: "9" }
            ListElement { color: "lightsteelblue" ; text: "10" }
            ListElement { color: "lightsteelblue" ; text: "11" }
            ListElement { color: "lightsteelblue" ; text: "12" }
            ListElement { color: "lightsteelblue" ; text: "13" }
            ListElement { color: "lightsteelblue" ; text: "14" }
            ListElement { color: "lightsteelblue" ; text: "15" }
            ListElement { color: "transparent"  }
        }

        delegate: MouseArea {
            id: delegateRoot

            property int visualIndex: DelegateModel.itemsIndex

            width: 80; height: 80
            drag.target: icon

            Rectangle {
                id: icon
                Text {
                   text: model.text
                   font.pointSize: 30
                   anchors.centerIn: parent
                }
                width: 72; height: 72
                anchors {
                    horizontalCenter: parent.horizontalCenter;
                    verticalCenter: parent.verticalCenter
                }
                color: model.color
                radius: 3

                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 {
                anchors { fill: parent; margins: 15 }
                onEntered: {visualModel.items.move(drag.source.visualIndex, delegateRoot.visualIndex)}
            }
        }
    }
}


推荐答案

我尝试了一些尝试,但是到处都是错误。希望对您有所帮助。

I tried something but still few bugs here and there. Hope it helps.

import QtQuick 2.0
import QtQml.Models 2.1

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

displaced: Transition {
    NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad }//Animação anima a transicao dos tiles
}

model: DelegateModel {
    id: visualModel
    model: ListModel {
        id: colorModel
        ListElement { color: "lightsteelblue" ; text: "1" }
        ListElement { color: "lightsteelblue" ; text: "2" }
        ListElement { color: "lightsteelblue" ; text: "3" }
        ListElement { color: "lightsteelblue" ; text: "4" }
        ListElement { color: "lightsteelblue" ; text: "5" }
        ListElement { color: "lightsteelblue" ; text: "6" }
        ListElement { color: "lightsteelblue" ; text: "7" }
        ListElement { color: "lightsteelblue" ; text: "8" }
        ListElement { color: "lightsteelblue" ; text: "9" }
        ListElement { color: "lightsteelblue" ; text: "10" }
        ListElement { color: "lightsteelblue" ; text: "11" }
        ListElement { color: "lightsteelblue" ; text: "12" }
        ListElement { color: "lightsteelblue" ; text: "13" }
        ListElement { color: "lightsteelblue" ; text: "14" }
        ListElement { color: "lightsteelblue" ; text: "15" }
        ListElement { color: "transparent" ; text:"" }
    }

    delegate: MouseArea {
        id: delegateRoot
        property bool held: false
        property int visualIndex: DelegateModel.itemsIndex

        width: 80; height: 80
        drag.target: held ? icon : undefined
        drag.axis: Drag.XAndYAxis
        drag.minimumX: delegateRoot.x-75
        drag.minimumY: delegateRoot.y-75
        drag.maximumX: delegateRoot.x + 85
        drag.maximumY: delegateRoot.y + 85

        onPressed: {
                            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
            Text {
               text: model.text
               font.pointSize: 30
               anchors.centerIn: parent
            }
            width: 72; height: 72
            anchors {
                horizontalCenter: parent.horizontalCenter;
                verticalCenter: parent.verticalCenter
            }
            color: model.color
            radius: 3

            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 {
            anchors {
                                   fill: parent
                                   margins: 15
                    }
            onDropped: {
                var sourceNumber = colorModel.get(drag.source.visualIndex).text;
                var targetNumber = colorModel.get(delegateRoot.visualIndex).text;
                var sourceColor = colorModel.get(drag.source.visualIndex).color;
                var targetColor = colorModel.get(delegateRoot.visualIndex).color;
                colorModel.setProperty(drag.source.visualIndex, "text", targetNumber);
                colorModel.setProperty(delegateRoot.visualIndex, "text", sourceNumber);
                colorModel.setProperty(drag.source.visualIndex, "color", targetColor);
                colorModel.setProperty(delegateRoot.visualIndex, "color", sourceColor);
            }
        }
    }
}
}

这篇关于在GridView中交换元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆