[Solved] dynamic reparenting?



  • Hi folks,

    can somebody help me with the following problem?

    Setup: I have rectangles which can be dragged around with the mouse and there are DropAreas where the rectangles can be dropped. Each DropArea has a Layout where a dropped rectangle should be placed in.

    A dropped rectangle "arrives" at the onDropped-handler of the DropArea.
    The log-method prints out something like:
    qml: DropArea.onDropped: QQuickRectangle(0xa579cf7e90)
    Now I want to assign a new parent to the rectangle but this does not work.

    How can this be done?

    Here is my code (only the important DropArea-part):

    @ DropArea {
    anchors.fill: parent
    onDropped: {
    console.log( "DropArea.onDropped: " + drop.source.toString() )
    // How to reparent? New parent should be myLayout here
    }

                    ColumnLayout {
                        id: myLayout
    
                        anchors.horizontalCenter: parent.horizontalCenter
                        anchors.bottom: parent.bottom
                        anchors.bottomMargin: 0
                        spacing: 2
    
                        Rectangle {
                            width: 50
                            height: 50
                            color: "yellow"
                        }
                    }
                }
            }@
    

    Many thanks in advance.
    Kai


  • Moderators

    Hi,

    You can do
    @
    drop.source.parent = newParent //assign new parent here
    @

    Also don't forget to accept the drop.



  • Hmmm,

    does not work! What am I doing wrong?

    I paste the whole, runnable example. Maybe someone can check my code? I have inserted the new lines of code at row 148.

    What is wrong?

    @
    import QtQuick 2.3
    import QtQuick.Window 2.2
    import QtQuick.Layouts 1.1

    Window {
    visible: true
    width: 600
    height: 360

    Rectangle {
        id: globalBase
        anchors.fill: parent
        radius: 5
    
        border {
            color: "red"
            width:  2
        }
    
        Text {
            anchors {
                left: parent.left
                top: parent.top
                topMargin: 10
                leftMargin: 10
            }
    
            text: "base"
        }
    
        RowLayout {
    
            spacing: 10
            anchors.fill: parent
            anchors.margins: 50
    
            Rectangle {
    
                radius: 5
                border {
                    color: "green"
                    width:  2
                }
    
                Layout.fillWidth: true
                Layout.fillHeight: true
    
                Text {
                    anchors {
                        left: parent.left
                        top: parent.top
                        topMargin: 10
                        leftMargin: 10
                    }
    
                    text: "Drag Area"
                }
    
                ColumnLayout {
                    anchors.horizontalCenter: parent.horizontalCenter
                    anchors.bottom: parent.bottom
                    anchors.bottomMargin: 0
                    spacing: 2
    
                    Rectangle {
                        width: 50
                        height: 50
                        color: "yellow"
                    }
    
                    Rectangle {
                        id: dragTile
    
                        width: 50
                        height: 50
    
                        radius: 5
                        border {
                            color: "green"
                            width:  2
                        }
    
                        Drag.active: mouseArea.drag.active
                        Drag.hotSpot.x: 10
                        Drag.hotSpot.y: 10
    
                        Text {
                            anchors.centerIn: parent
                            text: "drag"
                        }
    
                        states: [
                            State {
                                when: mouseArea.drag.active
                                ParentChange { target: dragTile; parent: globalBase }
                            },
                            State {
                                name: "REPARENT"
                                ParentChange {
                                    id: myparentchange
                                }
                            }
    
                        ]
    
                        MouseArea {
                            id: mouseArea
                            anchors.fill: parent
                            drag.target: dragTile
    
                            onReleased: {
                                dragTile.Drag.drop()
                            }
                        }
                    }
                }
            }
    
            Rectangle {
    
                id: dropRect
    
                radius: 5
                border {
                    color: "blue"
                    width:  2
                }
    
                Layout.fillWidth: true
                Layout.fillHeight: true
    
    
                Text {
                    anchors {
                        left: parent.left
                        top: parent.top
                        topMargin: 10
                        leftMargin: 10
                    }
    
                    text: "Drop Area"
                }
    
                DropArea {
                    anchors.fill: parent
                    onDropped: {
                        console.log( "DropArea.onDropped: " + drop.source.toString() )
                        drop.source.parent = myLayout
                        drop.accept()
                    }
    
                    ColumnLayout {
                        id: myLayout
    
                        anchors.horizontalCenter: parent.horizontalCenter
                        anchors.bottom: parent.bottom
                        anchors.bottomMargin: 0
                        spacing: 2
    
                        Rectangle {
                            width: 50
                            height: 50
                            color: "yellow"
                        }
                    }
                }
            }
        }
    }
    

    }
    @


  • Moderators

    I guess its because of the ParentChange state which executes while the drag is still active. Remove it and use
    @
    parent: mouseArea.drag.active ? globalBase : currentLayout
    @

    Here currentLayout being the ColumnLayout which contains the Rectangle named "drag"



  • Hi p3c0,

    thanks for your answers. Your proposed solutions work.
    And yes the main-problem is the interference of the ParentChange and the drag-handling.

    BTW: I found a different solution:

    In the onReleased-handler I reset the state first. This let me keep the ParentChange-handling.

    @ onReleased: {
    dragTile.state = ""
    dragTile.Drag.drop()
    }@


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.