在GridView中交换元素 [英] Swap elements in a 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:
-
从网格中交换两个元素,拖放
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屋!