QML 动态视图排序教程 3 - 移动拖拽项

在应用程序中,下一步是要在拖拽时移动列表中的项,以便我们可以重新排序列表。为了实现这一点,我们在应用程序中引入了三种新的类型;DelegateModelDragDropArea

Rectangle {
    id: root

    width: 300
    height: 400

    Component {
        id: dragDelegate

        MouseArea {
            id: dragArea

            property bool held: false
            required property string name
            required property string type
            required property string size
            required property int age

            anchors {
                left: parent?.left
                right: parent?.right
            }
            height: content.height

            drag.target: held ? content : undefined
            drag.axis: Drag.YAxis

            onPressAndHold: held = true
            onReleased: held = false

            Rectangle {
                id: content
                Drag.active: dragArea.held
                Drag.source: dragArea
                Drag.hotSpot.x: width / 2
                Drag.hotSpot.y: height / 2
            }
            DropArea {
                anchors {
                    fill: parent
                    margins: 10
                }

                onEntered: (drag) => {
                    visualModel.items.move(
                            drag.source.DelegateModel.itemsIndex,
                            dragArea.DelegateModel.itemsIndex)
                }
            }
        }
    }
}
操作步骤

为了重新排序视图,我们需要确定何时一个项目被拖拽到另一个项目上。使用拖拽关联属性,我们可以生成在拖拽项移动时发送到场景图的事件。

                Drag.active: dragArea.held
                Drag.source: dragArea
                Drag.hotSpot.x: width / 2
                Drag.hotSpot.y: height / 2

拖拽事件仅在活动属性为 true 时发送,因此在这个例子中,第一个事件会在委托被持有时发送,当拖拽时,还会发送额外的事件。在拖拽项内的相对位置由hotSpot 属性指定,本例中为项的中心。

然后,在每个视图项中使用 DropArea 来确定拖拽项的热点是否与另一个项相交,当拖拽进入这些 DropArea 之一时,我们可以将拖拽项移动到拖拽项覆盖项的索引。

            DropArea {
                anchors {
                    fill: parent
                    margins: 10
                }

                onEntered: (drag) => {
                    visualModel.items.move(
                            drag.source.DelegateModel.itemsIndex,
                            dragArea.DelegateModel.itemsIndex)
                }
            }

为了在视图中移动项,我们使用 DelegateModel。视图类型使用 DelegateModel 类型来从模型数据实例化委托项,当显式构建时,可以用来筛选和重新排序提供给 ListView 的模型项。在不需要修改源模型的情况下,通过 items 属性,我们可以访问视图的项并更改可见顺序,DelegateModel 类型的 itemsIndex {itemsIndex} 属性用于确定委托项的当前可见索引。

要使用 DelegateModelListView,将其绑定到视图的 model 属性上,并将 modeldelegate 绑定到 DelegateModel

    DelegateModel {
        id: visualModel

        model: PetsModel {}
        delegate: dragDelegate
    }

    ListView {
        id: view

        anchors {
            fill: parent
            margins: 2
        }

        model: visualModel

        spacing: 4
        cacheBuffer: 50
    }

示例项目 @ code.qt.io

© 2024 The Qt Company Ltd. 本文档中包含的文档贡献的版权归其各自的所有者。本文档提供的内容受 GNU 自由文档许可证版本 1.3 的条款约束,此许可证由自由软件基金会发布。Qt 及其相应的标志是芬兰以及全球其他地区的 The Qt Company Ltd. 的商标。所有其他商标均为其各自所有者的财产。