我想使用 ListView 为我的游戏创建一个库存 UI,其中可以通过在关卡中拖放项目来将其从库存中删除。如果某个物品没有正确放置(仍在物品栏内),则应将其放回拖动前的位置。
我有以下代码,但即使在查看了之后我也不知道如何实现我想要的拖放示例 http://qt-project.org/doc/qt-5/qtquick-draganddrop-example.html.
import QtQuick 2.3
Rectangle {
id: root
width: 400
height: 400
ListView {
id: listView
width: parent.width / 2
height: parent.height
model: ListModel {
Component.onCompleted: {
for (var i = 0; i < 10; ++i) {
append({value: i});
}
}
}
delegate: Item {
id: delegateItem
width: listView.width
height: 50
Rectangle {
id: dragRect
width: listView.width
height: 50
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
color: "salmon"
border.color: Qt.darker(color)
Text {
anchors.centerIn: parent
text: modelData
}
MouseArea {
id: mouseArea
anchors.fill: parent
drag.target: dragRect
}
Drag.hotSpot.x: dragRect.width / 2
Drag.hotSpot.y: dragRect.height / 2
}
}
}
Rectangle {
width: parent.width / 2
height: parent.height
anchors.right: parent.right
color: "#aaff0011"
DropArea {
id: dropArea
anchors.fill: parent
}
}
}
您可以使用以下代码来实现此目的:
import QtQuick 2.3
Rectangle {
id: root
width: 400
height: 400
ListView {
id: listView
width: parent.width / 2
height: parent.height
property int dragItemIndex: -1
model: ListModel {
Component.onCompleted: {
for (var i = 0; i < 10; ++i) {
append({value: i});
}
}
}
delegate: Item {
id: delegateItem
width: listView.width
height: 50
Rectangle {
id: dragRect
width: listView.width
height: 50
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
color: "salmon"
border.color: Qt.darker(color)
Text {
anchors.centerIn: parent
text: modelData
}
MouseArea {
id: mouseArea
anchors.fill: parent
drag.target: dragRect
drag.onActiveChanged: {
if (mouseArea.drag.active) {
listView.dragItemIndex = index;
}
dragRect.Drag.drop();
}
}
states: [
State {
when: dragRect.Drag.active
ParentChange {
target: dragRect
parent: root
}
AnchorChanges {
target: dragRect
anchors.horizontalCenter: undefined
anchors.verticalCenter: undefined
}
}
]
Drag.active: mouseArea.drag.active
Drag.hotSpot.x: dragRect.width / 2
Drag.hotSpot.y: dragRect.height / 2
}
}
}
Rectangle {
width: parent.width / 2
height: parent.height
anchors.right: parent.right
color: "#aaff0011"
DropArea {
id: dropArea
anchors.fill: parent
onDropped: {
listView.model.remove(listView.dragItemIndex);
listView.dragItemIndex = -1;
}
}
}
}
在这个例子中需要注意一些事情:
我们存储dragItemIndex
这样我们就知道哪个项目被拖动。我们也许可以通过查看 DropArea 来实现同样的目标拖拽源 http://qt-project.org/doc/qt-5/qml-qtquick-droparea.html#drag.source-prop属性,但是我们必须在委托中公开一个索引属性,并且文档不鼓励在代表中存储状态 http://qt-project.org/doc/qt-5/qml-qtquick-listview.html#example-usage.
为了实现“项目被放回拖动失败时的位置”功能,我们做了dragRect
实际委托项目的子项,以便它有一个要坚持的父项。如果我们不这样做,该项目的父级将是 ListView,并且当未成功放置时,它只会位于上次拖动的位置。
我们使用与拖放示例 http://qt-project.org/doc/qt-5/qtquick-draganddrop-example.html#tiles;拖动时,我们希望从项目中删除锚点并让它自由拖动。如果拖动失败,when
状态的条件(dragRect.Drag.active
) 变为 false,并且该项目的父级回到尚未从列表视图中的原始位置移动的委托项目。锚也被恢复。这是国家的一个有用的特征;能够隐式恢复以前的状态。
In the MouseArea
's drag.onActiveChanged
信号处理程序,我们称之为dragRect.Drag.drop()
以便我们可以响应该事件DropArea
's onDropped
信号处理程序,并删除该项目。该项目被删除后,我们重置dragItemIndex
到无效的索引。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)