Auf dieser Seite

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 / 2

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

Beispielprojekt @ code.qt.io

© 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.