Skip to content

Instantly share code, notes, and snippets.

@csuft
Created June 8, 2018 03:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save csuft/0d4eded5828fbf64c2a5e30ad670e715 to your computer and use it in GitHub Desktop.
Save csuft/0d4eded5828fbf64c2a5e30ad670e715 to your computer and use it in GitHub Desktop.
drag and drop in qml listview
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
ApplicationWindow {
id: root
width: 780
height: 150
visible: true
ListView {
id: listView
anchors.fill: parent
orientation: ListView.Horizontal
addDisplaced: Transition {
NumberAnimation {properties: "x, y"; duration: 100}
}
moveDisplaced: Transition {
NumberAnimation { properties: "x, y"; duration: 100 }
}
remove: Transition {
NumberAnimation { properties: "x, y"; duration: 100 }
NumberAnimation { properties: "opacity"; duration: 100 }
}
removeDisplaced: Transition {
NumberAnimation { properties: "x, y"; duration: 100 }
}
displaced: Transition {
NumberAnimation {properties: "x, y"; duration: 100}
}
model: ListModel {
id: listModel
ListElement {
width: 50
height: 50
color: 'red'
}
ListElement {
width: 100
height: 50
color: 'yellow'
}
ListElement {
width: 150
height: 50
color: 'green'
}
ListElement {
width: 100
height: 50
color: 'blue'
}
ListElement {
width: 50
height: 50
color: 'black'
}
ListElement {
width: 200
height: 50
color: 'gray'
}
}
delegate: Item {
id: delegateItem
width: model.width
height: model.height
Rectangle {
id: dragRect
width: model.width
height: model.height
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
color: model.color
border.color: Qt.darker(color)
property int dragItemIndex: index
MouseArea {
id: mouseArea
anchors.fill: parent
drag.target: dragRect
drag.onActiveChanged: {
if (mouseArea.drag.active) {
dragRect.dragItemIndex = index;
}
}
}
states: [
State {
when: dragRect.Drag.active
ParentChange {
target: dragRect
parent: listView
}
AnchorChanges {
target: dragRect
anchors.horizontalCenter: undefined
anchors.verticalCenter: undefined
}
}
]
Drag.active: mouseArea.drag.active
Drag.hotSpot.x: dragRect.width / 2
Drag.hotSpot.y: dragRect.height / 2
}
DropArea {
anchors.fill: parent
onEntered: {
console.log("dragged", drag.source.dragItemIndex);
console.log("moved", dragRect.dragItemIndex);
listModel.move(drag.source.dragItemIndex, listView.dragItemIndex, 1)
}
}
}
}
}
@Meriemi-git
Copy link

to make things work perfectly you need to add this signals listening inside MouseArea, this will reset the dragItemIndex with correct value after item moved inside listModel

 onReleased: {
       dragRect.dragItemIndex = index;
 }

I replace also the content of the onEntered callback with this (and i adopt the new syntax for avoid deprecated warning about injecting drag param) :

 onEntered: (drag) => {
    if (dragRect.dragItemIndex > -1) {
        listModel.move(drag.source.dragItemIndex, dragRect.dragItemIndex, 1);
        const buf = drag.source.dragItemIndex;
        drag.source.dragItemIndex = dragRect.dragItemIndex;
        dragRect.dragItemIndex = buf;
    }
}

With this few changes it's work like a charm even 6 years after with QT 6, so big thanks to you, you save my day and the destiny of my KDE plasma widget !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment