模型更新后,QML ListView的默认行为

时间:2019-06-19 15:25:09

标签: c++ qt qml

我有以下ListView,它们在C ++端使用QStringListModel更新setStringList时,总是显示列表的开头。

例如,用户可以在视图中上下滚动,并且在更新模型时,视图将返回列表的开头。

如何禁用此行为?

我还需要视图一次准确显示X个项目(在我的示例中为2个)。该视图本身不是可滚动的(interactive: false),但是用户可以通过在UI中的某个位置上单击Button的上下来导航列表。

有合适的方法吗? (在Is it possible to show only certain indexes of a QML listview?之后)

编辑:我为“ up / down”问题添加了2个功能,它似乎按预期工作,但是我仍然很想知道是否有更好的方法。

谢谢。

        ListView {
            id: view
            anchors.top = parent.top
            anchors.left = parent.left
            readonly property int visibleItems: 2
            readonly property int itemHeight: 20
            height: visibleItems * itemHeight
            width: 100
            clip: true

            model: listModel // a QStringListModel

            delegate: Rectangle {
                border.width: 1
                border.color: "black"
                height: view.itemHeight
                width: 100
                Text { text: model.display }
            }

            interactive: false

            function up() {
                var currentTopIndex =  indexAt(view.width / 2, contentY)

                if (currentTopIndex !== -1) {

                    var newTopIndex = currentTopIndex - view.visibleItems

                    if (newTopIndex >= 0)
                        view.positionViewAtIndex(newTopIndex, ListView.Beginning)
                 }
            }

            function down() {
                var currentTopIndex =  indexAt(view.width / 2, contentY)

                if (currentTopIndex !== -1) {

                    var newTopIndex = currentTopIndex + view.visibleItems

                    if (newTopIndex < view.count)
                        view.positionViewAtIndex(newTopIndex, ListView.Beginning)
                 }
            }

2 个答案:

答案 0 :(得分:1)

只要模型数据发生更改,就可以在ListView属性中添加此属性。在这里,我假设contentY不变。

contentX

如果只想显示某些项目,您可能还想添加property real previousContentY Connections { target: model onModelAboutToBeReset: view.previousContentY = view.contentY onModelReset: view.contentY = view.previousContentY }

答案 1 :(得分:0)

一种解决方案是用外部ListView包装Flickable,该外部ListView将负责滚动。

此解决方案不需要手动重置先前的contentY ListView,因为滚动位置不再依赖于Button { id: button text: 'change model' onClicked: view.aModel = !view.aModel } Flickable { anchors.top: button.bottom width: parent.width height: 100 interactive: true // the scroll will be managed by this external Flickable contentHeight: view.contentHeight clip: true ListView { id: view property bool aModel: true anchors.fill: parent interactive: false // deactivate scroll on the internal Flickable model: aModel ? ["a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a"] : ["b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b"] delegate: Text { width: parent.width height: 20 text: modelData + index } } } 本身。

这是一个基本的工作示例:

==