[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 -
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.1Window {
visible: true
width: 600
height: 360Rectangle { 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" } } } } } }
}
@ -
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()
}@