QML 動的ビューオーダリングチュートリアル 2 - ビュー項目をドラッグする

表示可能な項目リストができたので、それらを操作できるようにしたいと思います。まずはデリゲートを拡張して、表示されているコンテンツを画面の上下にドラッグできるようにします。更新されたデリゲートは次のようになります:

    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 }
                }
            }
        }
    }
チュートリアル

ここでの大きな変更は、デリゲートのルート・アイテムがMouseArea 、マウス・イベントのハンドラを提供し、デリゲートのコンテンツ・アイテムをドラッグできるようになったことです。また、デリゲートのルートアイテムはビューによって位置決めされ、他の手段では移動できないため、コンテンツアイテムのコンテナとしても機能します。

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

コンテンツアイテムのドラッグは、MouseAreadrag.target プロパティにバインドすることで可能になります。ビューをフリックできるようにしたいので、ドラッグ・ターゲットをバインドする前に、MouseArea'のpressAndHold シグナルが出るまで待ちます。こうすることで、ホールドタイムアウトが切れる前にマウスが動いた場合はリストを移動したと解釈され、タイムアウト後に動いた場合はアイテムをドラッグしたと解釈されます。アイテムがいつドラッグできるかをユーザーにわかりやすくするために、タイムアウトが過ぎたらコンテンツ・アイテムの背景色を変えるようにします。

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

アイテムをドラッグできるようにする前にしなければならないもう一つのことは、コンテンツアイテムのアンカーを解除して、自由に動かせるようにすることです。これは、デリゲートアイテムが保持されたときにトリガーされるステートチェンジで行います。同時に、コンテンツアイテムをルートアイテムに再ペアレントすることで、スタック順で他のアイテムの上にあり、ドラッグされても見えないようにします。

                states: State {
                    when: dragArea.held

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

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