我正在尝试在qml中实现拖放灵魂,而不使用模型和委托。因此,我创建了四个容器和四个具有不同颜色的矩形,我想移动这些矩形来拖动它们,当一个矩形放到另一个矩形上时,我需要交换位置。
到目前为止,我已经设法使用重排来简化该操作,但是第二次我尝试移动另一个矩形(或者它抱怨的那个矩形不能锚定为空项目(就像父级被破坏了一样)
它必须是使用列表或模型拖放白名单的另一种简便方法。我对此深表感谢。
import QtQuick 2.12
import QtQuick.Controls 2.3
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.0
ApplicationWindow{
id:root
minimumWidth: 1024
minimumHeight: 700
visible: true
title: "PlannerX2"
Component.onCompleted: {
root.showMaximized();
}
property int toIndex: -1
property int fromIndex: -1
property string sobreEscrito:""
property var posiciones: ["rojo","verde","azul","naranja"]
property var contenedores: ["vtk2dSceneAxialHolder","vtk2dSceneSagitalHolder","vtk2dSceneCoronalHolder","vtk3dSceneHolder"]
function returnFather( i)
{
switch (contenedores[i])
{
case "vtk2dSceneAxialHolder":
return vtk2dSceneAxialHolder
case "vtk2dSceneSagitalHolder":
return vtk2dSceneSagitalHolder
case "vtk2dSceneCoronalHolder":
return vtk2dSceneCoronalHolder
case "vtk3dSceneHolder":
return vtk3dSceneHolder
}
}
Rectangle {
id: screenCanvasUI
anchors.fill: parent
// Frame {
// id: view2dFrame
// visible: true
// rightPadding: 0
// leftPadding: 0
// topPadding: 0
// bottomPadding: 0
// width: parent.width/3
// anchors.left: parent.left
// anchors.top: parent.top
// anchors.bottom: parent.bottom
Rectangle{
id: vtk2dSceneAxialHolder
property int minHeight
height: parent.height/3
Layout.minimumHeight: minHeight
anchors.top: parent.top
anchors.left: parent.left
width: parent.width/3
DropArea{
anchors.fill: parent
onEntered: {
console.log("entrando en area Axial")
toIndex=0
}
onExited: {
console.log("saliendo de area Axial")
toIndex=-1
}
}
Rectangle{
id:rojo
color: "red"
width: parent.width
height: parent.height
Drag.active: rojoMouseArea.drag.active
Drag.hotSpot.x: rojo.width/2
Drag.hotSpot.y: rojo.height/2
property bool update:false
states:[
State{
name: "moving"
when: (rojo.Drag.active && verde.Drag.active===false && azul.Drag.active===false&& naranja.Drag.active===false)
ParentChange{
target: rojo
parent: screenCanvasUI
}
AnchorChanges{
target:rojo
anchors.horizontalCenter: undefined
anchors.verticalCenter: undefined
anchors.left: undefined
anchors.right: undefined
anchors.bottom: undefined
anchors.top: undefined
}
PropertyChanges {
target: rojo
width: 200
height:200
anchors.left: undefined
anchors.top: undefined
}
},
State{
name: "dropping"
when: (toIndex!==-1 && rojo.Drag.active===false && verde.Drag.active===false && azul.Drag.active===false&& naranja.Drag.active===false && toIndex!==-1 )
ParentChange{
target: rojo
parent:returnFather(posiciones.indexOf("rojo"))
}
PropertyChanges {
target: rojo
width: parent.width
height:parent.height
anchors.left: parent.left
anchors.top: parent.top
}
}
]
Item{
anchors.left: parent.left
anchors.top: parent.top
width: 20
height: 20
Frame{
anchors.fill:parent
}
MouseArea{
id:rojoMouseArea
anchors.fill: parent
drag.target: rojo
onClicked:
{
toIndex=-1
fromIndex=-1
console.log(screenCanvasUI)
console.log(toIndex)
console.log(fromIndex)
console.log(rojoMouseArea.drag.active)
}
drag.onActiveChanged: {
if (rojoMouseArea.drag.active)
{
console.log(toIndex)
console.log(fromIndex)
toIndex=-1
rojo.update=false
azul.update=false
verde.update=false
naranja.update=false
fromIndex=posiciones.indexOf("rojo");
console.log(toIndex)
console.log(fromIndex)
}
else{
var temp= posiciones[fromIndex];
posiciones[fromIndex]=posiciones[toIndex]
posiciones[toIndex]=temp;
rojo.Drag.drop()
}
}
}
}
}
}
Rectangle{
id: vtk2dSceneSagitalHolder
anchors.left: parent.left
anchors.top :vtk2dSceneAxialHolder.bottom
height: parent.height/3
width: parent.width/3
DropArea{
anchors.fill: parent
onEntered: {
console.log("entrando en area Sagital")
toIndex=1
}
onExited: {
console.log("saliendo de area Sagital")
toIndex=-1
}
}
Rectangle{
id:verde
color: "green"
width: parent.width
height: parent.height
property bool update:false
Drag.active: verdeMouseArea.drag.active
Drag.hotSpot.x: verde.width/2
Drag.hotSpot.y: verde.height/2
states:[
State{
name: "moving"
when: (verde.Drag.active && rojo.Drag.active===false && azul.Drag.active===false && naranja.Drag.active===false)
ParentChange{
target: verde
parent: screenCanvasUI
}
AnchorChanges{
target:verde
anchors.horizontalCenter: undefined
anchors.verticalCenter: undefined
anchors.left: undefined
anchors.right: undefined
anchors.bottom: undefined
anchors.top: undefined
}
PropertyChanges {
target: verde
width: 200
height:200
anchors.left: undefined
anchors.top: undefined
}
},
State{
name: "dropping"
when: ( toIndex!==-1 && verde.Drag.active===false && rojo.Drag.active===false && azul.Drag.active===false && naranja.Drag.active===false)
ParentChange{
target: verde
parent:returnFather(posiciones.indexOf("verde"))//{contenedores[toIndex]}
}
PropertyChanges {
target: verde
width: parent.width
height:parent.height
anchors.left: parent.left
anchors.top: parent.top
}
}
]
Item{
anchors.left: parent.left
anchors.top: parent.top
width: 20
height: 20
Frame{
anchors.fill:parent
}
MouseArea{
id:verdeMouseArea
anchors.fill: parent
drag.target: verde
drag.onActiveChanged: {
if (verdeMouseArea.drag.active)
{
toIndex=-1
fromIndex=posiciones.indexOf("verde");
rojo.update=false
azul.update=false
verde.update=false
naranja.update=false
}
else{
var temp= posiciones[fromIndex];
posiciones[fromIndex]=posiciones[toIndex]
posiciones[toIndex]=temp;
verde.Drag.drop();
}
}
}
}
}
}
Rectangle{
id: vtk2dSceneCoronalHolder
height: parent.height/3
anchors.left: parent.left
anchors.bottom: parent.bottom
width: parent.width/3
DropArea{
anchors.fill: parent
onEntered: {
console.log("entrando en area Coronal")
toIndex=2
}
onExited: {
console.log("saliendo de area Coronal")
toIndex=-1
}
}
Rectangle{
id:azul
color: "blue"
width: parent.width
height: parent.height
property bool update:false
Drag.active: azulMouseArea.drag.active
Drag.hotSpot.x: azul.width/2
Drag.hotSpot.y: azul.height/2
states:[
State{
name: "moving"
when: (azul.Drag.active && verde.Drag.active===false && rojo.Drag.active===false&& naranja.Drag.active===false)
ParentChange{
target: azul
parent: screenCanvasUI
}
AnchorChanges{
target:azul
anchors.horizontalCenter: undefined
anchors.verticalCenter: undefined
anchors.left: undefined
anchors.right: undefined
anchors.bottom: undefined
anchors.top: undefined
}
PropertyChanges {
target: azul
width: 200
height:200
anchors.left: undefined
anchors.top: undefined
}
},
State{
name: "dropping"
when: (toIndex!== -1 && azul.Drag.active===false && verde.Drag.active===false && rojo.Drag.active===false&& naranja.Drag.active===false )
ParentChange{
target: azul
parent:returnFather(posiciones.indexOf("azul"))//{contenedores[toIndex]}
}
PropertyChanges {
target: azul
width: parent.width
height:parent.height
anchors.left: parent.left
anchors.top: parent.top
}
}
]
Item{
anchors.left: parent.left
anchors.top: parent.top
width: 20
height: 20
Frame{
anchors.fill:parent
}
MouseArea{
id:azulMouseArea
anchors.fill: parent
drag.target: azul
drag.onActiveChanged: {
if (azulMouseArea.drag.active)
{
toIndex=-1
fromIndex=posiciones.indexOf("azul");
rojo.update=false
azul.update=false
verde.update=false
naranja.update=false
}
else{
var temp= posiciones[fromIndex];
posiciones[fromIndex]=posiciones[toIndex]
posiciones[toIndex]=temp;
azul.Drag.drop();
}
}
}
}
}
}
}
//}
Rectangle{
id: vtk3dSceneHolder
width: parent.width*2/3
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
DropArea{
id: vtk3dDropArea
anchors.fill: parent
onEntered: {
console.log("entrando en area 3D")
toIndex=3
}
onExited: {
console.log("saliendo de area 3D")
toIndex=-1
}
}
Rectangle{
id:naranja
color: "orange"
width: parent.width
height: parent.height
property bool update:false
Drag.active: naranjaMouseArea.drag.active
Drag.hotSpot.x: naranja.width/2
Drag.hotSpot.y: naranja.height/2
states:[
State{
name:"moving"
when: (naranja.Drag.active && rojo.Drag.active===false && verde.Drag.active===false && azul.Drag.active===false)
ParentChange{
target: naranja
parent: screenCanvasUI
}
AnchorChanges{
target:naranja
anchors.horizontalCenter: undefined
anchors.verticalCenter: undefined
anchors.left: undefined
anchors.right: undefined
anchors.bottom: undefined
anchors.top: undefined
}
PropertyChanges {
target: naranja
width: 200
height:200
anchors.left: undefined
anchors.top: undefined
}
},
State{
name: "dropping"
when: (toIndex!=-1 && naranja.Drag.active===false && rojo.Drag.active===false && verde.Drag.active===false && azul.Drag.active===false)
ParentChange{
target:naranja
parent: returnFather(posiciones.indexOf("naranja"))//{contenedores[fromIndex] }
}
PropertyChanges {
target: naranja
width: parent.width
height:parent.height
anchors.left: parent.left
anchors.top: parent.top
update:false
}
}
]
Item{
anchors.left: parent.left
anchors.top: parent.top
width: 20
height: 20
Frame{
anchors.fill:parent
}
MouseArea{
id:naranjaMouseArea
anchors.fill: parent
drag.target: naranja
drag.onActiveChanged: {
if (naranjaMouseArea.drag.active)
{
toIndex=-1
fromIndex=posiciones.indexOf("naranja");
}
else{
var temp= posiciones[fromIndex];
posiciones[fromIndex]=posiciones[toIndex]
posiciones[toIndex]=temp;
naranja.Drag.drop();
}
}
}
}
}
}
}
正如我所说,第一次y拖动它可以工作,但是此后不再出现此错误:
qrc:/main.qml:388:13: QML Rectangle: Cannot anchor to a null item.
qrc:/main.qml:388:13: QML Rectangle: Cannot anchor to a null item.
qrc:/main.qml:248:13: QML Rectangle: Cannot anchor to a null item.
qrc:/main.qml:248:13: QML Rectangle: Cannot anchor to a null item.
qrc:/main.qml:85:13: QML Rectangle: Cannot anchor to a null item.
qrc:/main.qml:85:13: QML Rectangle: Cannot anchor to a null item.