Sur cette page

QML Dynamic View Ordering Tutorial 3 - Déplacer des éléments glissés

L'étape suivante de notre application consiste à déplacer les éléments de la liste au fur et à mesure qu'ils sont glissés, afin de pouvoir réorganiser la liste. Pour ce faire, nous introduisons trois nouveaux types dans notre application : DelegateModel, Drag et 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)
                }
            }
        }
    }
}
Présentation

Pour réorganiser la vue, nous devons déterminer si un élément a été glissé sur un autre. Grâce à la propriété Drag attached, nous pouvons générer des événements qui sont envoyés au graphe de scène chaque fois que l'élément auquel ils sont attachés se déplace.

                Drag.active: dragArea.held
                Drag.source: dragArea
                Drag.hotSpot.x: width / 2
                Drag.hotSpot.y: height / 2

Les événements de glissement ne sont envoyés que lorsque la propriété active est vraie. Dans cet exemple, le premier événement serait donc envoyé lorsque le délégué est maintenu et d'autres événements seraient envoyés lors du glissement. La propriété hotSpot spécifie la position relative des événements de déplacement dans l'élément déplacé, le centre de l'élément dans cet exemple.

Nous utilisons ensuite une adresse DropArea dans chaque élément de la vue pour déterminer quand le point chaud de l'élément glissé croise un autre élément. Lorsqu'un glissement entre dans l'une de ces DropAreas, nous pouvons déplacer l'élément glissé jusqu'à l'index de l'élément sur lequel il a été glissé.

            DropArea {
                anchors {
                    fill: parent
                    margins: 10
                }

                onEntered: (drag) => {
                    visualModel.items.move(
                            drag.source.DelegateModel.itemsIndex,
                            dragArea.DelegateModel.itemsIndex)
                }
            }

Pour déplacer les éléments dans la vue, nous utilisons un type DelegateModel. Le type DelegateModel est utilisé par les types de vue pour instancier des éléments délégués à partir de données de modèle et, lorsqu'il est construit explicitement, il peut être utilisé pour filtrer et réorganiser les éléments de modèle fournis à ListView. La propriété items de DelegateModel donne accès aux éléments de la vue et nous permet de modifier l'ordre visible sans modifier le modèle source. Pour déterminer l'indice visible actuel des éléments, nous utilisons la propriété itemsIndex {itemsIndex} sur la propriété DelegateModel attachée à l'élément délégué.

Pour utiliser un DelegateModel avec un ListView, nous le lions à la propriété model de la vue et nous lions les model et delegate à la propriété DelegateModel.

    DelegateModel {
        id: visualModel

        model: PetsModel {}
        delegate: dragDelegate
    }

    ListView {
        id: view

        anchors {
            fill: parent
            margins: 2
        }

        model: visualModel

        spacing: 4
        cacheBuffer: 50
    }

Exemple de projet @ 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.