如何通过拖放

时间:2019-06-03 15:20:03

标签: listview qml tableview qt-creator

是否具有重新排列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
        }
    }
}

1 个答案:

答案 0 :(得分:0)

发现了我的问题-上面的示例确实是正确的。但是,在我的机器上,我的实现花费了很长的时间才能启动MouseArea的pressAndHold操作。我将其更改为pressed