QML-Tutorial zur dynamischen Anordnung von Ansichten 3 – Verschieben gezogener Elemente
Der nächste Schritt in unserer Anwendung besteht darin, Elemente beim Ziehen innerhalb der Liste zu verschieben, damit wir die Liste neu anordnen können. Dazu führen wir drei neue Typen in unsere Anwendung ein: „ DelegateModel “, „ Drag “ und „ DropArea “.
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)
}
}
}
}
}Schritt-für-Schritt-Anleitung
Um die Ansicht neu zu ordnen, müssen wir feststellen, wann ein Element über ein anderes gezogen wurde. Mit der angehängten Eigenschaft „Drag“ können wir Ereignisse generieren, die an den Szenengraphen gesendet werden, sobald sich das Element, an das sie angehängt ist, bewegt.
Drag.active: dragArea.held
Drag.source: dragArea
Drag.hotSpot.x: width / 2
Drag.hotSpot.y: height / 2Drag-Ereignisse werden nur gesendet, solange die Eigenschaft „active“ auf „true“ gesetzt ist; in diesem Beispiel würde das erste Ereignis also gesendet, wenn die Maustaste gedrückt gehalten wird, und weitere Ereignisse würden beim Ziehen folgen. Die Eigenschaft „ hotSpot “ gibt die relative Position der Drag-Ereignisse innerhalb des gezogenen Elements an, in diesem Fall die Mitte des Elements.
Anschließend verwenden wir in jedem View-Element ein „ DropArea “, um festzustellen, wann der Hotspot des gezogenen Elements ein anderes Element schneidet; sobald ein Drag in einen dieser „DropAreas“ gelangt, können wir das gezogene Element an den Index des Elements verschieben, über das es gezogen wurde.
DropArea {
anchors {
fill: parent
margins: 10
}
onEntered: (drag) => {
visualModel.items.move(
drag.source.DelegateModel.itemsIndex,
dragArea.DelegateModel.itemsIndex)
}
}Um die Elemente innerhalb der Ansicht zu verschieben, verwenden wir ein „ DelegateModel “. Der Typ „ DelegateModel “ wird von den Ansichtstypen verwendet, um Delegate-Elemente aus Modelldaten zu instanziieren, und kann, wenn er explizit erstellt wird, zum Filtern und Neuanordnen der an „ ListView “ übergebenen Modellelemente verwendet werden. Die Eigenschaft „ items “ von „ DelegateModel “ bietet Zugriff auf die Elemente der Ansicht und ermöglicht es uns, die sichtbare Reihenfolge zu ändern, ohne das Quellmodell zu modifizieren. Um den aktuell sichtbaren Index der Elemente zu ermitteln, verwenden wir die Eigenschaft ` itemsIndex {itemsIndex}` der angehängten Eigenschaft ` DelegateModel ` des Delegat-Elements.
Um eine „ DelegateModel “ mit einer „ ListView “ zu verwenden, binden wir sie an die Eigenschaft „ model “ der Ansicht und binden die Eigenschaften „ model “ und „ delegate “ an „ DelegateModel “.
DelegateModel {
id: visualModel
model: PetsModel {}
delegate: dragDelegate
}
ListView {
id: view
anchors {
fill: parent
margins: 2
}
model: visualModel
spacing: 4
cacheBuffer: 50
}© 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.