QML 動的ビューオーダーのチュートリアル 3 - ドラッグした項目の移動

このアプリケーションの次のステップは、ドラッグされたアイテムをリスト内で移動させ、リストを並べ替えることです。これを実現するために、DelegateModelDragDropArea の3つの新しい型をアプリケーションに導入します。

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)
                }
            }
        }
    }
}
ウォークスルー

ビューを再順序付けするためには、あるアイテムが他のアイテムの上にドラッグされたときを判断する必要があります。Drag attachedプロパティを使うと、アイテムが動くたびにシーングラフに送られるイベントを生成できます。

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

Drag イベントは、active プロパティが true の間だけ送信されるので、この例では、デリゲートが保持されているときに最初のイベントが送信され、ドラッグ時に追加のイベントが送信されます。hotSpot プロパティは、ドラッグされたアイテム内でのドラッグイベントの相対位置を指定します。

そして、ドラッグされたアイテムのホットスポットが他のアイテムと交差するときを決定するために、各ビューアイテムのDropArea 。ドラッグがこれらのDropAreaの1つに入ると、ドラッグされたアイテムを、ドラッグされたアイテムのインデックスに移動させることができます。

            DropArea {
                anchors {
                    fill: parent
                    margins: 10
                }

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

ビュー内でアイテムを移動するには、DelegateModel を使用します。DelegateModel 型は、ビュー型によってモデルデータからデリゲートアイテムをインスタンス化するために使用され、明示的に構築された場合には、ListView に提供されたモデルアイテムをフィルタリングして順序を変更するために使用することができます。DelegateModelitems プロパティは、ビューのアイテムへのアクセスを提供し、ソースモデルを変更することなく可視順序を変更することを可能にします。アイテムの現在の可視インデックスを決定するには、デリゲート・アイテムのDelegateModel アタッチ・プロパティのitemsIndex {itemsIndex}プロパティを使用します。

ListViewDelegateModel を利用するには、ビューのmodel プロパティにバインドし、modeldelegateDelegateModel にバインドします。

    DelegateModel {
        id: visualModel

        model: PetsModel {}
        delegate: dragDelegate
    }

    ListView {
        id: view

        anchors {
            fill: parent
            margins: 2
        }

        model: visualModel

        spacing: 4
        cacheBuffer: 50
    }

プロジェクト例 @ 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.