I have a menu with grouped components (qtreeview). I want to drag them into another treeview.
I have the following (menu) treeview
TreeView {
id: menuView
Layout.minimumWidth: 50
Layout.fillHeight: true
rowDelegate: Item {
height: 30
}
height: parent.height
property int dragItemIndex: -1
itemDelegate: dndDelegate
model: myModel
onCurrentIndexChanged: console.log("current index", currentIndex)
TableViewColumn {
title: "Name"
resizable: false
}
}
/*Delegate for displaying treeview item*/
Component {
id: dndDelegate
Item {
DraggableArea{}
}
}
/*Draggable area*/
MouseArea {
id:mouseArea
onPressed: Code.startDrag(mouse);
onPositionChanged: Code.continueDrag(mouse);
onReleased: Code.endDrag(mouse)
anchors { left: parent.left; right: parent.right }
height: dragRect.height
width:dragRect.width
drag.target: dragRect
Rectangle {
id: dragRect
Image {
id: menuItemImage
anchors.leftMargin: 5
anchors.left:parent.left // set anchor to be able to set margin
anchors.verticalCenter:parent.verticalCenter
source:model ? model.CommandIcon:""
}
Text {
anchors.left:menuItemImage.right
anchors.verticalCenter:parent.verticalCenter
text:model ? model.CommandTitle:""
anchors.leftMargin: 5
font.pixelSize: 14
}
width: menuView.width - 50
color: "red"
border.color: "black"
border.width: 2
radius: 4
height: 27
}
}
TreeView {
id: menuView
Layout.minimumWidth: 50
Layout.fillHeight: true
rowDelegate: Item {
height: 30
}
height: parent.height
property int dragItemIndex: -1
itemDelegate: dndDelegate
model: myModel
onCurrentIndexChanged: console.log("current index", currentIndex)
TableViewColumn {
title: "Name"
resizable: false
}
}
/*Delegate for displaying treeview item*/
Component {
id: dndDelegate
Item {
DraggableArea{}
}
}
/*Draggable area*/
MouseArea {
id:mouseArea
onPressed: Code.startDrag(mouse);
onPositionChanged: Code.continueDrag(mouse);
onReleased: Code.endDrag(mouse)
anchors { left: parent.left; right: parent.right }
height: dragRect.height
width:dragRect.width
drag.target: dragRect
Rectangle {
id: dragRect
Image {
id: menuItemImage
anchors.leftMargin: 5
anchors.left:parent.left // set anchor to be able to set margin
anchors.verticalCenter:parent.verticalCenter
source:model ? model.CommandIcon:""
}
Text {
anchors.left:menuItemImage.right
anchors.verticalCenter:parent.verticalCenter
text:model ? model.CommandTitle:""
anchors.leftMargin: 5
font.pixelSize: 14
}
width: menuView.width - 50
color: "red"
border.color: "black"
border.width: 2
radius: 4
height: 27
}
}
To copy to clipboard, switch view to plain text mode
and the javascript code to drag by copying the items
var itemComponent = null;
var draggedItem = null;
var startingMouse;
var posnInWindow;
function startDrag(mouse)
{
posnInWindow = dragRect.mapToItem(root, 0, 0);
console.debug("posnInWindow: "+ posnInWindow.x + " " + posnInWindow.y);
startingMouse = { x: mouse.x, y: mouse.y }
console.debug("startingMouse: "+ startingMouse.x + " " + startingMouse.y);
loadComponent();
}
//Creation is split into two functions due to an asynchronous wait while
//possible external files are loaded.
function loadComponent() {
if (itemComponent != null) { // component has been previously loaded
createItem();
return;
}
itemComponent = Qt.createComponent("../DraggableArea.qml");
if (itemComponent.status == Component.Loading) //Depending on the content, it can be ready or error immediately
component.statusChanged.connect(createItem);
else
createItem();
}
function createItem() {
if (itemComponent.status == Component.Ready && draggedItem == null) {
draggedItem = itemComponent.createObject(root, {"x": 40,
"y": posnInWindow.y});
draggedItem.anchors.left = undefined;
draggedItem.anchors.right = undefined;
console.debug("draggedItem created: "+ draggedItem.x + " " + draggedItem.y);
// make sure created item is above the ground layer
}
else if (itemComponent.status == Component.Error) {
draggedItem = null;
console.log("error creating component");
console.log(itemComponent.errorString());
}
}
function continueDrag(mouse)
{
if (draggedItem == null)
return;
draggedItem.x = mouse.x + posnInWindow.x - startingMouse.x;
draggedItem.y = mouse.y + posnInWindow.y - startingMouse.y;
//console.debug("mouse: "+ mouse.x + " " + mouse.y);
//console.debug("posnInWindow: "+ posnInWindow.x + " " + posnInWindow.y);
//console.debug("startingMouse: "+ startingMouse.x + " " + startingMouse.y);
//console.debug("draggedItem: "+ draggedItem.x + " " + draggedItem.y);
}
function endDrag(mouse)
{
draggedItem.destroy();
/*if (draggedItem == null)
return;
if (draggedItem.y < toolbox.height) { //Don't drop it in the toolbox
draggedItem.destroy();
draggedItem = null;
} else {
draggedItem.created = true;
draggedItem = null;
}*/
draggedItem = null;
//draggedItem.created = true;
}
var itemComponent = null;
var draggedItem = null;
var startingMouse;
var posnInWindow;
function startDrag(mouse)
{
posnInWindow = dragRect.mapToItem(root, 0, 0);
console.debug("posnInWindow: "+ posnInWindow.x + " " + posnInWindow.y);
startingMouse = { x: mouse.x, y: mouse.y }
console.debug("startingMouse: "+ startingMouse.x + " " + startingMouse.y);
loadComponent();
}
//Creation is split into two functions due to an asynchronous wait while
//possible external files are loaded.
function loadComponent() {
if (itemComponent != null) { // component has been previously loaded
createItem();
return;
}
itemComponent = Qt.createComponent("../DraggableArea.qml");
if (itemComponent.status == Component.Loading) //Depending on the content, it can be ready or error immediately
component.statusChanged.connect(createItem);
else
createItem();
}
function createItem() {
if (itemComponent.status == Component.Ready && draggedItem == null) {
draggedItem = itemComponent.createObject(root, {"x": 40,
"y": posnInWindow.y});
draggedItem.anchors.left = undefined;
draggedItem.anchors.right = undefined;
console.debug("draggedItem created: "+ draggedItem.x + " " + draggedItem.y);
// make sure created item is above the ground layer
}
else if (itemComponent.status == Component.Error) {
draggedItem = null;
console.log("error creating component");
console.log(itemComponent.errorString());
}
}
function continueDrag(mouse)
{
if (draggedItem == null)
return;
draggedItem.x = mouse.x + posnInWindow.x - startingMouse.x;
draggedItem.y = mouse.y + posnInWindow.y - startingMouse.y;
//console.debug("mouse: "+ mouse.x + " " + mouse.y);
//console.debug("posnInWindow: "+ posnInWindow.x + " " + posnInWindow.y);
//console.debug("startingMouse: "+ startingMouse.x + " " + startingMouse.y);
//console.debug("draggedItem: "+ draggedItem.x + " " + draggedItem.y);
}
function endDrag(mouse)
{
draggedItem.destroy();
/*if (draggedItem == null)
return;
if (draggedItem.y < toolbox.height) { //Don't drop it in the toolbox
draggedItem.destroy();
draggedItem = null;
} else {
draggedItem.created = true;
draggedItem = null;
}*/
draggedItem = null;
//draggedItem.created = true;
}
To copy to clipboard, switch view to plain text mode
The problem is that these dynamically created items aren't perceived as draggable (I just emulate dragging changing coordinates in JS). How to do it right, like it works in QTreeView approach? Setting drag.target for newly created object doesn't seem to work (get an exception)
Bookmarks