QML Dynamic View Ordering Tutorial 2 - Ziehen von Ansichtselementen

Nun, da wir eine sichtbare Liste von Elementen haben, wollen wir in der Lage sein, mit ihnen zu interagieren. Wir beginnen mit der Erweiterung des Delegaten, so dass der sichtbare Inhalt nach oben und unten auf dem Bildschirm gezogen werden kann. Der aktualisierte Delegat sieht wie folgt aus:

    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 }
                }
            }
        }
    }
Komplettlösung

Die wichtigste Änderung ist, dass das Wurzelelement des Delegaten jetzt ein MouseArea ist, das Handler für Mausereignisse bereitstellt und uns erlaubt, das Inhaltselement des Delegaten zu ziehen. Es fungiert auch als Container für das Inhaltselement, was wichtig ist, da das Stammelement eines Delegaten von der Ansicht positioniert wird und nicht mit anderen Mitteln verschoben werden kann.

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

Das Ziehen des Inhaltselements wird durch die Bindung an die Eigenschaft drag.target von MouseArea ermöglicht. Da die Ansicht immer noch flickbar sein soll, warten wir, bis das Signal pressAndHold von MouseArea ausgegeben wird, bevor wir das Ziehziel binden. Wenn sich die Maus bewegt, bevor die Haltezeit abgelaufen ist, wird dies als Verschieben der Liste interpretiert, und wenn sie sich danach bewegt, wird dies als Ziehen eines Elements interpretiert. Um es für den Benutzer deutlicher zu machen, wann ein Element gezogen werden kann, werden wir die Hintergrundfarbe des Inhaltselements ändern, wenn die Zeitüberschreitung abgelaufen ist.

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

Bevor ein Element gezogen werden kann, müssen wir außerdem alle Verankerungen des Inhaltselements aufheben, damit es frei bewegt werden kann. Wir tun dies in einer Zustandsänderung, die ausgelöst wird, wenn das delegierte Element gehalten wird, zur gleichen Zeit können wir das Inhaltselement auf das Stammelement reparieren, so dass es über anderen Elementen in der Stapelreihenfolge liegt und nicht verdeckt wird, wenn es herumgezogen wird.

                states: State {
                    when: dragArea.held

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

Beispielprojekt @ 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.