在上一篇介绍了单个ListView内部单元的相互拖动功能,这里则在上一篇基础上增加了一些复杂性,增加了两个ListView控件之间单元的相互拖动,并在拖动时显示拖动单元的具体内容。
实现方法 :拖动方法使用上一篇的同样的方法,只是在超过控件范围(如右边Listview控件的最左边),则会做出:将右侧Listview控件正在拖动的单元append添加到左侧ListView控件,然后remove移除当前被拖动的单元。对于拖动时显示拖动的单元,则可以单独定义一个rectangle控件,里面的text变量为拖动单元内容,通过mousearea的一些移动属性来实现拖动时的跟随效果。好,下面上程序啦。
参考程序:
import QtQuick 2.3
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
Rectangle {
width: 800
height: 600
ListModel{
id: objmodel
ListElement{
name: "苹果"
cost: "5000"
manufacturer: "Apple公司"
}
ListElement{
name: "小米2"
cost: "2000"
manufacturer: "小米公司"
}
ListElement{
name: "三星"
cost: "3000"
manufacturer: "三星公司"
}
}
property int first_index: -1
property int last_index: -1
Component {
id: phone_delegate
Item {
id: wrapper
width: parent.width
height: 30
Row{
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
spacing: 8
Text {
id: coll
text: name
color: wrapper.ListView.isCurrentItem? "red":"black"
font.pixelSize: 20
}
Text {
text: cost
color: wrapper.ListView.isCurrentItem? "red":"black"
font.pixelSize: 20
}
Text {
text: manufacturer
color: wrapper.ListView.isCurrentItem? "red":"black"
font.pixelSize: 20
}
}
MouseArea {
id: mousearea
anchors.fill: parent
onClicked: {
}
onPressed: {
}
onReleased: {
}
onMouseXChanged: {
var pore = listview.indexAt( mousearea.mouseX + wrapper.x, mousearea.mouseY + wrapper.y );
if( index != pore ) {
objmodel.move( index, pore , 1)
}
}
onMouseYChanged: {
var pore = listview.indexAt( mousearea.mouseX + wrapper.x, mousearea.mouseY + wrapper.y );
if( index != pore ) {
objmodel.move( index, pore , 1)
}
}
}
}
}
ListView {
id: listview
anchors.left: parent.left
width: 300
height: 300
delegate: phone_delegate
model:objmodel
interactive: false
focus: true
move: Transition {
NumberAnimation { properties: "x,y"; duration: 100 }
}
}
ListModel{
id: second_model
ListElement{
name: "苹果"
cost: "5000"
manufacturer: "Apple公司"
}
ListElement{
name: "小米2"
cost: "2000"
manufacturer: "小米公司"
}
ListElement{
name: "三星"
cost: "3000"
manufacturer: "三星公司"
}
}
Component {
id: android_delegate
Item {
id: second_wrapper
width: parent.width
height: 30
Row{
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
spacing: 8
Text {
id: coll
text: name
color: second_wrapper.ListView.isCurrentItem? "red":"black"
font.pixelSize: 20
}
Text {
text: cost
color: second_wrapper.ListView.isCurrentItem? "red":"black"
font.pixelSize: 20
}
Text {
text: manufacturer
color: second_wrapper.ListView.isCurrentItem? "red":"black"
font.pixelSize: 20
}
}
Text {
id: txt
text: second_model.get( index ).name + " " + second_model.get( index ).cost + " " + second_model.get( index ).manufacturer
visible: false
}
MouseArea {
id: mousearea
anchors.fill: parent
drag.target: txt
drag.axis: Drag.XAndYAxis
// drag.axis: Drag.XAxis
drag.minimumX: mouseX
drag.maximumX: 0
drag.minimumY: mouseY
drag.maximumY: second_wrapper.height
onClicked: {
}
onPressed: {
pre_index = second_view.currentIndex
console.log( "pre" + pre_index )
txt.x = mouseX
txt.y = mouseY
// if( mouseX < 0 ) {
txt.visible = true
// }
}
onReleased: {
rel_index = second_view.currentIndex
console.log("re:" + rel_index )
console.log( "x:" +mouseX+"y:"+mouseY)
if( mouseX < 0) {
console.log( "hello" + second_model.get( index ) )
objmodel.append( second_model.get( index ) )
second_model.remove( index )
}
txt.visible = false
}
onMouseXChanged: {
var pore = second_view.indexAt( mousearea.mouseX + second_wrapper.x, mousearea.mouseY + second_wrapper.y );
if( index != pore ) {
second_model.move( index, pore , 1)
}
}
onMouseYChanged: {
var pore = second_view.indexAt( mousearea.mouseX + second_wrapper.x, mousearea.mouseY + second_wrapper.y );
if( index != pore ) {
second_model.move( index, pore , 1)
}
}
}
}
}
property int n_flag: 0
ListView {
id: second_view
anchors.left: listview.right
width: 300
height: 300
delegate: android_delegate
model: second_model
interactive: false
focus: true
function move_down() {
if( ( n_flag == 0 ) && ( currentIndex+1 ) < second_model.count ) {
model.move( currentIndex, currentIndex+1, 1)
}
if( n_flag == 1 && ( currentIndex-1 ) >= 0) {
model.move( currentIndex, currentIndex-1, 1)
}
if( currentIndex -1 == 0 ) {
n_flag = 0;
}
if( currentIndex + 1 == second_model.count ) {
n_flag = 1
}
}
move: Transition {
NumberAnimation { properties: "x, y"; duration: 100 }
}
// remove: Transition {
// SequentialAnimation {
// NumberAnimation {
// properties: "x, y"
// to:0
// duration: 500
// }
// NumberAnimation {
// properties: "opacity"
// duration: 1
// }
// }
// }
}
Rectangle {
anchors.bottom: parent.bottom
anchors.right: parent.right
width: 100
height: 100
border.width: 0.6
MouseArea {
anchors.fill: parent
onClicked: {
console.log( second_view.currentIndex )
second_view.move_down()
}
}
}
}