反转ListView而不从底部填充ListView

时间:2015-02-13 09:38:41

标签: listview qml qt-quick

我希望ListView反转其项目的顺序,以便最新的项目位于顶部。 我尝试使用verticalLayoutDirection: ListView.BottomToTop实现此目的,但它会使ListView从底部填满(我想是可以预料的。)

我用红色标记了所述ListView的实际边界。 enter image description here

如何反转ListView的项目顺序并仍然从上到下填充?清洁工越多越好。

根据要求,提供更多信息:

ListView
{
    id: theList

    anchors
    {
        left: parent.left
        top: theAboveList.bottom
        right: parent.right
        bottom: parent.bottom
    }

    model: theModel
    delegate: theDelegate {}
    verticalLayoutDirection: ListView.BottomToTop
    clip: true
}

为什么我需要将其反转,是因为委托实例知道它们何时位于最底层(我可以在委托中执行index === 0),以设置某个状态。

4 个答案:

答案 0 :(得分:2)

如果我理解正确,我想到的第一个想法是使用模型并操纵C++ Qt side中的模型。但是这项任务需要更多的耐心并且只需要一点点开销。

另一种方法是将模型作为典型的JavaScript列表进行操作 - 填充它,然后手动反转。

此代码非常简单:

function swap(a, b) {
    if (a < b) {
        move(a, b, 1)
        move (b-1, a, 1)
    } else if (a > b) {
        move(b, a, 1)
        move (a-1, b, 1)
    }
}

function reverse() {
    for (var i = 0; i < Math.floor(count/2); ++i) {
        swap(i, count-i-1)
    }
}

在这里,您可以找到我写的AdvancedListModel的源代码 - https://github.com/troyane/StackOverflow-pro/tree/master/AdvModel_qml

答案 1 :(得分:2)

另一种解决方案是使用ListModel的{​​{3}}。在现有索引中插入值不会压缩先前的值。它改变了它。

以下是一个例子:

myModel.append({myValue: "Hello"})
myModel.insert(0, {myValue: "Goodbye"})

输出:

Goodbye
Hello

答案 2 :(得分:1)

我现在通过将ListView的height-property设置为contentHeight来解决它。我原本想避免这种解决方案,因为可能存在布局问题(绑定循环等),但它现在必须要做。

答案 3 :(得分:1)

this other answer上构建,但是遵循它以便它适用于任何大小的模型,如果没有足够的话,可以使用header组件中的spacer来将代理推送到顶层填写视图。

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0

ApplicationWindow {
    visible: true
    width: 640
    height: 480

    property var theModel: 2

    Component {
        id: theDelegate
        Rectangle {
            height: 100
            border.width: 2
            border.color: "black"
            color: "red"
            width: ListView.view.width
            Text {
                width: parent.width
                text: index
                font.pointSize: 30
            }
        }
    }

    Item {
        id: theAboveList
        // component exists only to complete the example supplied in the question
    }

    ListView {
        id: theList

        anchors
        {
            left: parent.left
            top: theAboveList.bottom
            right: parent.right
            bottom: parent.bottom
        }

        model: theModel
        delegate: theDelegate
        verticalLayoutDirection: ListView.BottomToTop
        clip: true

        header: Item {}
        onContentHeightChanged: {
            if (contentHeight < height) {
                headerItem.height += (height - contentHeight)
            }
            currentIndex = count-1
            positionViewAtEnd()
        }
    }
}