View Item gets dropped outside drop area in qml

2019-03-02 17:12发布

I implemented an Gridview and it has different images in them i need to drag items out of the grid view and place it in a DropArea. I followed How to drag an item outside a ListView in QML But now my grid item can be dragged throughout the page anywhere.I need to restrict this to the DropArea. It also has the layering issue in grid items. I am trying to bring the dragged tile to the topmost view I am completely fresh to Qt

Here is my code

import QtQuick 2.0

Item {

    id: media_item
    anchors.fill: parent



    Rectangle
    {
        y: 100
        id: holder_box
        width: 450
        height: 150
        color: "#99000000"
        radius: 5

        GridView {
            id: grid
            anchors.fill: parent
            model: mediaModel
            delegate:  Item {
                id: main_item
                width: grid.cellWidth;
                height: grid.cellHeight


                Rectangle {
                    id: item; parent: grid
                    color: mediagraphic
                    x: main_item.x; y: main_item.y
                    width: 100; height: 100;

                    Behavior on x { NumberAnimation { duration: 400; easing.type: Easing.OutBack } }
                    Behavior on y { NumberAnimation { duration: 400; easing.type: Easing.OutBack } }
                }
                Drag.active: mouseArea.drag.active
                Drag.hotSpot.x: main_item.width / 2
                Drag.hotSpot.y: main_item.height / 2


                MouseArea {
                    id: mouseArea
                    anchors.fill: main_item
                    drag.target: main_item

                    drag.onActiveChanged: {
                        if (mouseArea.drag.active) {
                            grid.dragItemIndex = index;
                        }
                        main_item.Drag.drop();
                    }
                }

                states: [

                    State {
                        name: 'dragged'
                        when: main_item.Drag.active
                        PropertyChanges {
                            target: main_item
                            x: x
                            y: y
                        }
                        ParentChange
                        {
                            target: main_item
                            parent: topDrag
                        }
                    }
                ]

                onStateChanged: console.log('State', state)
            }
            interactive: false
            anchors.topMargin: -30

            property int dragItemIndex: -1

        }




        ListModel {
            id: mediaModel
            ListElement { mediagraphic: "orchid"
                songname: "Song 1"}
            ListElement {mediagraphic: "pink"
                songname: "Song 2"}
            ListElement {mediagraphic: "purple"
                songname: "Song 3"}
            ListElement {mediagraphic: "lighpink"
                songname: "Song 4"}
            ListElement {mediagraphic: "blue"
                songname: "Song 5"}
            ListElement {mediagraphic: "grey"
                songname: "Song 6"}
        }


        Component
        {
            id: grid_component

            Item {
                id: main_item
                width: grid.cellWidth;
                height: grid.cellHeight


                Rectangle {
                    id: item; parent: grid
                    color: mediagraphic
                    x: main_item.x; y: main_item.y
                    width: 100; height: 100;

                    Behavior on x { NumberAnimation { duration: 400; easing.type: Easing.OutBack } }
                    Behavior on y { NumberAnimation { duration: 400; easing.type: Easing.OutBack } }
                }
                Drag.active: mouseArea.drag.active
                Drag.hotSpot.x: main_item.width / 2
                Drag.hotSpot.y: main_item.height / 2


                MouseArea {
                    id: mouseArea
                    anchors.fill: main_item
                    drag.target: main_item

                    drag.onActiveChanged: {
                        if (mouseArea.drag.active) {
                            grid.dragItemIndex = index;
                        }
                        main_item.Drag.drop();
                    }
                }

                states: [

                    State {
                        name: 'dragged'
                        when: main_item.Drag.active
                        PropertyChanges {
                            target: main_item
                            x: x
                            y: y
                        }
                        ParentChange
                        {
                            target: main_item
                            parent: media_item
                        }
                    }
                ]

                onStateChanged: console.log('State', state)
            }
        }

    }

    Rectangle
    {
        id: now_playing_rect
        height: parent.height
        width: parent.width/2
        x: 640
        color: "Transparent"


        DropArea
        {
            id: dropArea
            width: 200
            height: 200
            anchors.centerIn: parent
            onDropped:
            {
                song_details.text = grid.model.get(grid.dragItemIndex).songname
                selected_song_image.color =  grid.model.get(grid.dragItemIndex).mediagraphic
                mediaModel.remove(grid.dragItemIndex)
            }
        }

        Rectangle {
            id: selected_song_image
            width: 200
            height: 200
            anchors.centerIn: parent
        }

        Rectangle {
            id: next
            color: 'green'
            anchors.verticalCenter: now_playing_rect.verticalCenter
            anchors.left: dropArea.right
            width: 50
            height: 50
        }

        Rectangle {
            id: previous
            color: 'brown'
            anchors.verticalCenter: now_playing_rect.verticalCenter
            anchors.right: dropArea.left
            width: 50
            height: 50
        }

        Text {
            id: song_details
            text: qsTr("Song Title")
            anchors.top: dropArea.bottom
            font.pointSize: 30
            color: "White"
            anchors.horizontalCenter: parent.horizontalCenter
        }
    }

    Item {
        id: topDrag
        anchors.fill: parent
    }
}

标签: qt gridview qml
1条回答
太酷不给撩
2楼-- · 2019-03-02 17:47

I edited your Example. As I had no Images, I changed everything to Rectangles with colors, to make it running.

For future note, it would be nice, if I could run your example from the beginning.

The main change, you are looking for is in the states. By setting a "ChangeProperty" for x and y, they will be resetted when the state changes back.

Item {

    id: media_item
    anchors.fill: parent



    Rectangle
    {
        y: 100
        id: holder_box
        width: 450
        height: 150
        color: "#99000000"
        radius: 5

        GridView {
            id: grid
            anchors.fill: parent
            model: mediaModel
            delegate: grid_component
            interactive: false
            anchors.topMargin: -30

            property int dragItemIndex: -1

        }




        ListModel {
            id: mediaModel
            ListElement { mediagraphic: "orchid"
                songname: "Song 1"}
            ListElement {mediagraphic: "pink"
                songname: "Song 2"}
            ListElement {mediagraphic: "purple"
                songname: "Song 3"}
            ListElement {mediagraphic: "lighpink"
                songname: "Song 4"}
            ListElement {mediagraphic: "blue"
                songname: "Song 5"}
            ListElement {mediagraphic: "grey"
                songname: "Song 6"}
        }


        Component
        {
            id: grid_component

            Item {
                id: main_item
                width: grid.cellWidth;
                height: grid.cellHeight


                Rectangle {
                    id: item; parent: grid
                    color: mediagraphic
                    x: main_item.x; y: main_item.y
                    width: 100; height: 100;

                    Behavior on x { NumberAnimation { duration: 400; easing.type: Easing.OutBack } }
                    Behavior on y { NumberAnimation { duration: 400; easing.type: Easing.OutBack } }
                }
                Drag.active: mouseArea.drag.active
                Drag.hotSpot.x: main_item.width / 2
                Drag.hotSpot.y: main_item.height / 2


                MouseArea {
                    id: mouseArea
                    anchors.fill: main_item
                    drag.target: main_item

                    drag.onActiveChanged: {
                        if (mouseArea.drag.active) {
                            grid.dragItemIndex = index;
                        }
                        main_item.Drag.drop();
                    }
                }

                states: [

                    State {
                        name: 'dragged'
                        when: main_item.Drag.active
                        PropertyChanges {
                            target: main_item
                            x: x
                            y: y
                        }
                    }
                ]

                onStateChanged: console.log('State', state)
            }
        }

    }

    Rectangle
    {
        id: now_playing_rect
        height: parent.height
        width: parent.width/2
        x: 640
        color: "Transparent"


        DropArea
        {
            id: dropArea
            width: 200
            height: 200
            anchors.centerIn: parent
            onDropped:
            {
                song_details.text = grid.model.get(grid.dragItemIndex).songname
                selected_song_image.color =  grid.model.get(grid.dragItemIndex).mediagraphic
                mediaModel.remove(grid.dragItemIndex)
            }
        }

        Rectangle {
            id: selected_song_image
            width: 200
            height: 200
            anchors.centerIn: parent
        }

        Rectangle {
            id: next
            color: 'green'
            anchors.verticalCenter: now_playing_rect.verticalCenter
            anchors.left: dropArea.right
            width: 50
            height: 50
        }

        Rectangle {
            id: previous
            color: 'brown'
            anchors.verticalCenter: now_playing_rect.verticalCenter
            anchors.right: dropArea.left
            width: 50
            height: 50
        }

        Text {
            id: song_details
            text: qsTr("Song Title")
            anchors.top: dropArea.bottom
            font.pointSize: 30
            color: "White"
            anchors.horizontalCenter: parent.horizontalCenter
        }
    }
}

I think it should behave as expected?

Please do not forget to accept my answer, if it is what you were looking for.

查看更多
登录 后发表回答