QML 动态视图排序教程 2 - 拖动视图项

既然我们已经有一个可见的项列表,我们希望与之交互。我们将首先扩展 delegate,以便可见内容可以拖动到屏幕的上下位置。更新的 delegate 看起来像这样

    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
                anchors {
                    horizontalCenter: parent.horizontalCenter
                    verticalCenter: parent.verticalCenter
                }
                width: dragArea.width
                height: column.implicitHeight + 4

                border.width: 1
                border.color: "lightsteelblue"
                color: dragArea.held ? "lightsteelblue" : "white"
                Behavior on color { ColorAnimation { duration: 100 } }
                radius: 2
                states: State {
                    when: dragArea.held

                    ParentChange {
                        target: content
                        parent: root
                    }
                    AnchorChanges {
                        target: content
                        anchors {
                            horizontalCenter: undefined
                            verticalCenter: undefined
                        }
                    }
                }
                Column {
                    id: column
                    anchors {
                        fill: parent
                        margins: 2
                    }

                    Text { text: qsTr('Name: ') + dragArea.name }
                    Text { text: qsTr('Type: ') + dragArea.type }
                    Text { text: qsTr('Age: ') + dragArea.age }
                    Text { text: qsTr('Size: ') + dragArea.size }
                }
            }
        }
    }
操作步骤

这里的主要变化是 delegate 的根项现在是一个 MouseArea,它提供鼠标事件处理器,并可允许我们拖动 delegate 的内容项。它还作为内容项的容器,这在 delegate 的根项由视图定位且不能通过其他方式移动时很重要。

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

通过将内容项绑定到 MouseAreadrag.target 属性来启用内容项的拖动。因为我们仍然想要可滚动的视图,所以我们会在 MouseAreapressAndHold 信号发出之前绑定拖动目标。这样,当鼠标在保持时间限制到期之前移动时,它被解释为移动列表;如果它在持续时间之后移动,则被解释为拖动一个项。为了使用户更明显地知道何时可以拖动项,我们将在超时时间到时改变内容项的背景颜色。

                color: dragArea.held ? "lightsteelblue" : "white"
                Behavior on color { ColorAnimation { duration: 100 } }

在项可以拖动之前需要做的另一件事是取消内容项上的任何锚点,以便它可以自由地移动。我们通过在委托项被持有时触发的状态变化来完成此操作,同时我们可以把内容项重新定位到根项,这样它就在堆叠顺序中的其他项之上,并且在拖动时不会受阻。

                states: State {
                    when: dragArea.held

                    ParentChange {
                        target: content
                        parent: root
                    }
                    AnchorChanges {
                        target: content
                        anchors {
                            horizontalCenter: undefined
                            verticalCenter: undefined
                        }
                    }
                }

示例项目 @ code.qt.io

© 2024 The Qt Company Ltd. 于此处包含的文档贡献是各自所有者的版权。此处的文档是根据自由软件基金会发布并由其发布的 GNU 自由文档许可证版本 1.3 的条款许可的。Qt 和相关商标是芬兰以及全世界其他国家的 The Qt Company Ltd. 的商标。所有其他商标均为其各自所有者的财产。