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
}
}通过将内容项绑定到MouseArea 的drag.target 属性,即可启用内容项的拖动功能。由于我们仍希望视图保持可轻扫状态,因此会在等待MouseArea 的pressAndHold 信号发出后,才绑定拖动目标。这样,当鼠标在按住超时结束前移动时,会被解释为移动列表;而在超时结束后移动时,则会被解释为拖动项目。 为了让用户更直观地知道何时可以拖动项目,我们将在超时结束后更改内容项的背景颜色。
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
}
}
}© 2026 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.