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

现在我们有了一个可见的项目列表,我们希望能与它们进行交互。我们首先要扩展委托,这样可见内容就可以在屏幕上下拖动了。更新后的委托看起来像这样:

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

这里的主要变化是委托的根项目现在是一个MouseArea ,它为鼠标事件提供了处理程序,并允许我们拖动委托的内容项目。它还充当了内容项的容器,这一点很重要,因为委托的根项是由视图定位的,不能通过其他方式移动。

        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

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.