5

私はhttp://qt-project.org/wiki/Drag_and_Drop_within_a_GridViewで与えられたアプローチに従っています。

私は提示されたプログラムを持っています。ドラッグ アンド ドロップは機能していますが、ドロップ後にグリッドに空きスペースができます。どうすればこれを改善できますか?

さらに、46 行目の関数 indexAt() がドラッグ操作中に正しく機能していないことにも気付きました。したがって、gridArea.index の明示的な計算を追加する必要がありました。

(編集済み)要素をドロップした後、元の位置に戻されるため(可視要素の下にある)、空のスペースが表示されるように思えます。GridView は更新されず、イレギュラーな状態で終了します。

import QtQuick 1.1

GridView {
    id: mainGrid
    cellWidth: 165; cellHeight: 95
    width: 5*cellWidth; height: 4*cellHeight
    model: myModel
    delegate: myButton

    ListModel {
        id: myModel
        function createModel() {
            for (var i=1; i<=20; i++) {
                myModel.append({"display": i, "uid": i})
            }
        }
        Component.onCompleted: {createModel()}
    }

    Component {
        id: myButton
        Rectangle {
            id: item
            width: mainGrid.cellWidth-5; height: mainGrid.cellHeight-5;
            border.width: 1
            property int uid: (index >= 0) ? myModel.get(index).uid : -1
            Text {
                anchors.centerIn: parent
                text: display
                font.pixelSize: 48
            }
            states: [
                State {
                    name: "active"; when: gridArea.activeId == item.uid
                    PropertyChanges {target: item; x: gridArea.mouseX-80; y: gridArea.mouseY-45; z: 10; smooth: false}
                }
            ]
        }
    }

    MouseArea {
        id: gridArea
        anchors.fill: parent
        hoverEnabled: true
        preventStealing : true
        //property int index: mainGrid.indexAt(mouseX, mouseY) //WHY IS THIS NOT WORKING RELIABLE?
        property int mX: (mouseX < 0) ? 0 : ((mouseX < mainGrid.width - mainGrid.cellWidth) ? mouseX : mainGrid.width - mainGrid.cellWidth)
        property int mY: (mouseY < 0) ? 0 : ((mouseY < mainGrid.height - mainGrid.cellHeight) ? mouseY : mainGrid.height - mainGrid.cellHeight)
        property int index: parseInt(mX/mainGrid.cellWidth) + 5*parseInt(mY/mainGrid.cellHeight)  //item underneath cursor
        property int activeId: -1 //uid of active item
        property int activeIndex //current position of active item
        onPressAndHold: {
            activeId = mainGrid.model.get(activeIndex=index).uid
        }
        onReleased: {
            activeId = -1
        }
        onPositionChanged: {
            if (activeId != -1 && index != -1 && index != activeIndex) {
                mainGrid.model.move(activeIndex, activeIndex = index, 1)
            }
        }
    }
}
4

2 に答える 2

4

ここで、作業コードを示します。階層を追加し、Rectangle を Item に入れました。さらに、Rectangle の親を変更する必要がありました。利用可能な同様のソリューションが多数あります

指定されたソリューションでは、関数 indexAt() に問題がないため、 gridArea.index の明示的な計算はもう必要ありません。

このソリューションと、これらの変更が非常に重要である理由についてコメントをいただければ幸いです。元のソリューションは直感的で、なぜ機能しないのかわかりません。

import QtQuick 1.1

GridView {
    id: mainGrid
    cellWidth: 165; cellHeight: 95
    width: 5*cellWidth; height: 4*cellHeight
    model: myModel
    delegate: myButton

    ListModel {
        id: myModel
        function createModel() {
            for (var i=1; i<=20; i++) {
                myModel.append({"display": i, "uid": i})
            }
        }
        Component.onCompleted: {createModel()}
    }

    Component {
        id: myButton
        Item {
            id: item
            width: mainGrid.cellWidth-5; height: mainGrid.cellHeight-5;
            Rectangle {
                id: box
                parent: mainGrid
                x: item.x; y: item.y;
                width: item.width; height: item.height;
                border.width: 1
                property int uid: (index >= 0) ? myModel.get(index).uid : -1
                Text {
                    anchors.centerIn: parent
                    text: display
                    font.pixelSize: 48
                }
                states: [
                    State {
                        name: "active"; when: gridArea.activeId == box.uid
                        PropertyChanges {target: box; x: gridArea.mouseX-80; y: gridArea.mouseY-45; z: 10}
                    }
                ]
            }
        }
    }

    MouseArea {
        id: gridArea
        anchors.fill: parent
        hoverEnabled: true
        preventStealing : true
        property int index: mainGrid.indexAt(mouseX, mouseY) //item underneath cursor
        property int activeId: -1 //uid of active item
        property int activeIndex //current position of active item

        onPressAndHold: {
            activeId = mainGrid.model.get(activeIndex=index).uid
        }
        onReleased: {
            activeId = -1
        }
        onPositionChanged: {
            if (activeId != -1 && index != -1 && index != activeIndex) {
                mainGrid.model.move(activeIndex, activeIndex = index, 1)
            }
        }
    }
}
于 2012-12-20T10:35:38.347 に答える
1

これは、MouseArea のドラッグ プロパティを使用した別の回答です。奇妙ですが、このソリューションには関数 indexAt() に問題があります。さらに、x と y の Behavior を使用して素敵なスロー モーション効果を追加することはできないようです。

このソリューションに関するコメントも大歓迎です。

import QtQuick 1.1

GridView {
    id: mainGrid
    cellWidth: 165; cellHeight: 95
    width: 5*cellWidth; height: 4*cellHeight
    model: myModel
    delegate: myButton

    ListModel {
        id: myModel
        function createModel() {
            for (var i=1; i<=20; i++) {
                myModel.append({"display": i})
            }
        }
        Component.onCompleted: {createModel()}
    }

    Component {
        id: myButton
        Rectangle {
            id: item
            z: 1
            width: mainGrid.cellWidth-5; height: mainGrid.cellHeight-5;
            border.width: 1
            Text {
                anchors.centerIn: parent
                text: display
                font.pixelSize: 48
            }
        }
    }

    MouseArea {
        id: gridArea
        anchors.fill: parent
        hoverEnabled: true
        drag.axis: Drag.XandYAxis
        //property int index: mainGrid.indexAt(mouseX,mouseY) //NOT WORKING RELIABLE!
        property int mX: (mouseX < 0) ? 0 : ((mouseX < mainGrid.width - mainGrid.cellWidth) ? mouseX : mainGrid.width - mainGrid.cellWidth)
        property int mY: (mouseY < 0) ? 0 : ((mouseY < mainGrid.height - mainGrid.cellHeight) ? mouseY : mainGrid.height - mainGrid.cellHeight)
        property int index: parseInt(mX/mainGrid.cellWidth) + 5*parseInt(mY/mainGrid.cellHeight)  //item underneath cursor
        property int activeIndex

        onPressAndHold: {
            currentIndex = index
            currentItem.z = 10
            gridArea.drag.target = currentItem
            activeIndex = index
        }
        onReleased: {
            currentItem.x = mainGrid.cellWidth * (index % 5)
            currentItem.y = mainGrid.cellHeight * parseInt(index / 5)
            currentItem.z = 1
            currentIndex = -1
            gridArea.drag.target = null
        }
        onPositionChanged: {
            if (drag.active && index !== -1 && index !== activeIndex) {
                mainGrid.model.move(activeIndex, activeIndex = index, 1)
            }
        }
    }
}
于 2012-12-20T15:59:15.753 に答える