字符串数组模型更改时 ListView 不刷新

ListView does not refresh when string array model changes

添加新条目时,我的 ListView 不显示它们。

当对话框打开时,我将 QStringList 从 C++ 项目复制到 Qml 属性。 然后用户使用提供的控件修改数组(添加、修改、删除)。

遗憾的是,当我修改 属性 时,ListView 没有更新。 属性 已正确修改(如调试输出所示)。

如何使用数据绑定使 ListView 自动更新?

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    property var things

    Component.onCompleted: things = [] // normally retrieved from C++ QStringList

    ColumnLayout {
        anchors.fill: parent

        RowLayout {
            Layout.fillWidth: true

            TextField {
                Layout.fillWidth: true
                id: theTextField
            }

            Button {
                Layout.fillWidth: true
                text: qsTr("Append")
                onPressed: {
                    things.push(theTextField.text)
                    console.log(things)
                }
            }

            Button {
                Layout.fillWidth: true
                text: qsTr("Remove")
                onPressed: {
                    var index = things.indexOf(theTextField.text)
                    if(index == -1)
                        console.warn('Not found!')
                    else
                        things.splice(index, 1)
                    console.log(things)
                }
            }

            Button {
                Layout.fillWidth: true
                text: qsTr("Clear");
                onPressed: {
                    things = [];
                    console.log(things)
                }
            }
        }

        ListView {
            id: listView

            Layout.fillWidth: true
            Layout.fillHeight: true
            model: things
            delegate: Label {
                text: modelData
            }
        }
    }
}

原因是,使用函数修改things时没有thingsChanged信号。 things 中存储的引用将保持不变,无论您做什么。

对于 ListModel 这样的数据模型,这是相同的,但是存在 special signals 其中许多用于向任何视图指示它应该更新其内容。

如果您迫切需要使用数组,则需要手动调用 thingsChanged(),每当您更改数组内容时。但这仅表示整个数组已更改,View 的主要优势之一是无效 - 仅更改已更改内容的能力。

ViewthingsChanged 信号做出反应时,它会销毁所有当前委托,然后重新创建它们,无论是否有任何不同。

如果您使用 ListModelQAbstractItemModel-descendent,View 可以插入、删除或更改新委托的单个实例。

用真正的 ListModel 替换数组。使用函数追加!

Button {
            Layout.fillWidth: true
            text: qsTr("Clear");
            onPressed: {
                model.append({"data": theTextField.text})
            }
        }

and 在主块的 and 处 ListModel { id :model }