在QML開發中,ListView是我們經常用到的控件,可以用它給用戶展示出列表,但是往往都是將項目的顯示順序排好後,直接讓ListView顯示出來,亦或者是知道要移動到具體的那一位置,然後調整數據在ListView中的順序來達到要求,現有一種需求,就是用鼠標拖動某項,動態去改變某一項在ListView中顯示的順序位置,經過研究及實踐實戰,實現方式的核心代碼如下:
import QtQuick 2.4
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: "2500"
manufacturer: "小米公司"
}
ListElement{
name: "蘋果"
cost: "5000"
manufacturer: "Apple公司"
}
ListElement{
name: "小米2"
cost: "2000"
manufacturer: "小米公司"
}
ListElement{
name: "三星"
cost: "3000"
manufacturer: "三星公司"
}
ListElement{
name: "華爲"
cost: "3000"
manufacturer: "華爲公司"
}
ListElement{
name: "ViVo"
cost: "3000"
manufacturer: "ViVo公司"
}
}
Component {
id: com_delegate
Item {
id: wrapper
width: parent.width
height: 30
Rectangle {
id: bgColor
anchors.fill: parent
color: "transparent"
}
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: {
listview.currentIndex = index;
}
onPressed: {
bgColor.color = "blue"
}
onReleased: {
bgColor.color = "transparent"
}
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)
}
}
}
}
}
property int n_flag: 0
ListView {
id: listview
anchors.centerIn:parent
width: 300
height: 300
delegate: com_delegate
model:objmodel
interactive: false
focus: true
function move_down() {
if( ( n_flag == 0 ) && ( currentIndex+1 ) < 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 == model.count ) {
n_flag = 1
}
}
move: Transition {
NumberAnimation { properties: "x,y"; duration: 100 }
}
}
Rectangle {
anchors.bottom: parent.bottom
width: 100
height: 100
border.width: 0.6
MouseArea {
anchors.fill: parent
onClicked: {
console.log( listview.currentIndex )
listview.move_down()
}
}
}
}
鼠標拖動某項到指定的ListView中的某位置,然後放開鼠標,該項就移動到指定位置了。
左下角的框代表一個按鈕(雖然醜了點,說明問題就行^__^),點擊可以改變項的顯示位置。
具體的效果圖自己腦補,是在不行,直接拷貝以上代碼,用qmlscene運行,就可看到效果了。