是否具有重新排列QML列表视图(列表视图,表视图或其他)中的项目的功能?先前曾here未回答此问题。
我遵循了Qt Tutorial on Dynamic View Ordering,它最初并未在Qt-5.9中进行编译,因为它无法识别ListModel。我还尝试了this tutorial,它创建了下面的视图,但是没有重新排列;整个屏幕的移动就像一个滑动视图一样。我不确定这是否适用于旧版Qt,现在是否无法正常运行?
可以找到整个代码源here。我将在下面发布拖放功能:
MouseArea {
id: dragArea
anchors.fill: parent
property int positionStarted: 0
property int positionEnded: 0
property int positionsMoved: Math.floor((positionEnded - positionStarted)/starwarsNumberText.height)
property int newPosition: index + positionsMoved
property bool held: false
drag.axis: Drag.YAxis
onPressAndHold: {
starwarsDelegateBorder.z = 2,
positionStarted = starwarsDelegateBorder.y,
dragArea.drag.target = starwarsDelegateBorder,
starwarsDelegateBorder.opacity = 0.5,
starwarsList.interactive = false,
held = true
drag.maximumY = (wholeBody.height - starwarsNumberText.height - 1 + starwarsList.contentY),
drag.minimumY = 0
}
onPositionChanged: {
positionEnded = starwarsDelegateBorder.y;
}
onReleased: {
if (Math.abs(positionsMoved) < 1 && held == true) {
starwarsDelegateBorder.y = positionStarted,
starwarsDelegateBorder.opacity = 1,
starwarsList.interactive = true,
dragArea.drag.target = null,
held = false
} else {
if (held == true) {
if (newPosition < 1) {
starwarsDelegateBorder.z = 1,
starwarsModel.move(index,0,1),
starwarsDelegateBorder.opacity = 1,
starwarsList.interactive = true,
dragArea.drag.target = null,
held = false
} else if (newPosition > starwarsList.count - 1) {
starwarsDelegateBorder.z = 1,
starwarsModel.move(index,starwarsList.count - 1,1),
starwarsDelegateBorder.opacity = 1,
starwarsList.interactive = true,
dragArea.drag.target = null,
held = false
}
else {
starwarsDelegateBorder.z = 1,
starwarsModel.move(index,newPosition,1),
starwarsDelegateBorder.opacity = 1,
starwarsList.interactive = true,
dragArea.drag.target = null,
held = false
}
}
}
}
}
最小的可复制示例:
import QtQuick 2.9
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Rectangle {
id: wholeBody
width: 360
height: 360
ListModel {
id: starwarsModel
ListElement {
number: "IV"
title: "A New Hope"
}
ListElement {
number: "V"
title: "The Empire Strikes Back"
}
ListElement {
number: "VI"
title: "Return of the Jedi"
}
ListElement {
number: "I"
title: "The Phantom Menace"
}
ListElement {
number: "II"
title: "Attack of the Clones"
}
ListElement {
number: "III"
title: "Revenge of the Sith"
}
ListElement {
number: "VII"
title: "The Force of the Jedi"
}
ListElement {
number: "VIII"
title: "The New Republic Challenged"
}
ListElement {
number: "IX"
title: "The Force Combined"
}
ListElement {
number: "X"
title: "The Council Rebuilt"
}
ListElement {
number: "XI"
title: "Jedi Outnumbered"
}
ListElement {
number: "XII"
title: "The Ultimate Force"
}
}
Component {
id: starwarsDelegate
Rectangle {
id: starwarsDelegateBorder
border.color: "black"
width: wholeBody.width
height: starwarsNumberText.height
Row {
spacing: 10
Text { id: starwarsNumberText; text: number }
Text { text: title }
Text { text: index }
}
MouseArea {
id: dragArea
anchors.fill: parent
property int positionStarted: 0
property int positionEnded: 0
property int positionsMoved: Math.floor((positionEnded - positionStarted)/starwarsNumberText.height)
property int newPosition: index + positionsMoved
property bool held: false
drag.axis: Drag.YAxis
onPressAndHold: {
starwarsDelegateBorder.z = 2,
positionStarted = starwarsDelegateBorder.y,
dragArea.drag.target = starwarsDelegateBorder,
starwarsDelegateBorder.opacity = 0.5,
starwarsList.interactive = false,
held = true
drag.maximumY = (wholeBody.height - starwarsNumberText.height - 1 + starwarsList.contentY),
drag.minimumY = 0
}
onPositionChanged: {
positionEnded = starwarsDelegateBorder.y;
}
onReleased: {
if (Math.abs(positionsMoved) < 1 && held == true) {
starwarsDelegateBorder.y = positionStarted,
starwarsDelegateBorder.opacity = 1,
starwarsList.interactive = true,
dragArea.drag.target = null,
held = false
} else {
if (held == true) {
if (newPosition < 1) {
starwarsDelegateBorder.z = 1,
starwarsModel.move(index,0,1),
starwarsDelegateBorder.opacity = 1,
starwarsList.interactive = true,
dragArea.drag.target = null,
held = false
} else if (newPosition > starwarsList.count - 1) {
starwarsDelegateBorder.z = 1,
starwarsModel.move(index,starwarsList.count - 1,1),
starwarsDelegateBorder.opacity = 1,
starwarsList.interactive = true,
dragArea.drag.target = null,
held = false
}
else {
starwarsDelegateBorder.z = 1,
starwarsModel.move(index,newPosition,1),
starwarsDelegateBorder.opacity = 1,
starwarsList.interactive = true,
dragArea.drag.target = null,
held = false
}
}
}
}
}
}
}
ListView {
id: starwarsList
anchors.fill: parent
model: starwarsModel
delegate: starwarsDelegate
}
}
}
答案 0 :(得分:0)
发现了我的问题-上面的示例确实是正确的。但是,在我的机器上,我的实现花费了很长的时间才能启动MouseArea的pressAndHold
操作。我将其更改为pressed
。