Qt QML为什么不';这个ListView和ListModel不一致吗?

Qt QML为什么不';这个ListView和ListModel不一致吗?,qt,listview,qml,listmodel,Qt,Listview,Qml,Listmodel,我对列表视图和简单的列表模型有问题 import QtQuick 2.12 import QtQuick.Controls 2.12 ApplicationWindow { id: app visible: true width: 640 height: 480 property int bheight: 48 ListModel { id: jmodel } function dosomething1

我对
列表视图
和简单的
列表模型
有问题

import QtQuick 2.12
import QtQuick.Controls 2.12

ApplicationWindow
{
    id: app
    visible: true
    width: 640
    height: 480
    property int bheight: 48

    ListModel
    {
        id: jmodel
    }

    function dosomething1()
    {
        jmodel.clear();
        jmodel.append({"atext":"hello"})
    }

    function dosomething2()
    {
        jmodel.clear();
        jmodel.append({"atext":"hello","btext":"world"});
    }

    ListView
    {
        id: alist
        width: parent.width
        height: parent.height - bheight
        model: jmodel
        delegate: Item
        {
            width: app.width
            height: 48
            Row
            {
                spacing: 8
                Text
                {
                    text: model.atext || ""
                }

                Text
                {
                    text: model.btext || ""
                }
            }
        }
    }

    Row
    {
        height: bheight
        anchors.top: alist.bottom
        Button
        {
            // press "plan A" first and it will say "hello"
            // press "plan B" after and it will remain "hello"
            // pressing A & B will NOT toggle
            text: "Plan A"
            onClicked: dosomething1();
        }

        Button
        {
            // press "plan B" first and it will say "hello world"
            // press "plan A" after and it will say "hello"
            // pressing A & B will toggle
            text: "Plan B"
            onClicked: dosomething2();
        }
    }

}
我不能让它始终如一地工作。也许有一些简单的缺失或者我不明白

按“计划A”会说“你好”,按“计划B”后不会改变

但是,

首先按“Plan B”将显示“hello world”,然后按“Plan A”和“Plan B”将在“hello world”和“hello”之间切换

这不应该取决于首先按下的按钮,我每次都在清除模型

我在Qt5.12.3和5.9上试过这个,没有变化

更新 在@eyllanesc answer之后,我更新了代码,为每次更新创建了一个新模型。这是可行的,但我不知道我现在是否有内存泄漏

这是我的代码:

import QtQuick 2.12
import QtQuick.Controls 2.12

ApplicationWindow
{
    id: app
    visible: true
    width: 640
    height: 480
    property int bheight: 48

    Component
    {
        id: jmodel
        ListModel {}
    }

    function dosomething1()
    {
        var m = jmodel.createObject()
        m.append({"atext":"hello"})
        alist.model = m;
    }

    function dosomething2()
    {
        var m = jmodel.createObject()
        m.append({"atext":"hello","btext":"world"});
        alist.model = m;
    }

    ListView
    {
        id: alist
        width: parent.width
        height: parent.height - bheight
        delegate: Item
        {
            width: app.width
            height: 48
            Row
            {
                spacing: 8
                Text
                {
                    text: model.atext || ""
                }

                Text
                {
                    text: model.btext || ""
                }
            }
        }
    }

    Row
    {
        height: bheight
        anchors.top: alist.bottom
        Button
        {
            text: "Plan A"
            onClicked: dosomething1();
        }

        Button
        {
            text: "Plan B"
            onClicked: dosomething2();
        }
    }



}

正如我所指出的:

修改列表模型 修改列表模型可以创建和修改列表模型的内容 使用clear()、append()、set()、insert()和 setProperty()方法。例如:

Component {
    id: fruitDelegate
    Item {
        width: 200; height: 50
        Text { text: name }
        Text { text: '$' + cost; anchors.right: parent.right }

        // Double the price when clicked.
        MouseArea {
            anchors.fill: parent
            onClicked: fruitModel.setProperty(index, "cost", cost * 2)
        }
    }
} 
请注意,动态创建内容时,一旦设置了可用属性集,就无法更改。首先添加到模型中的任何属性都是模型中唯一允许的属性。

(增加重点)

初始建立属性后,不能添加或删除属性:

  • 在案例1中,您的模型最初只有atext属性,然后您希望添加btext属性,但Qt不允许

  • 在案例2中,您的模型具有属性atext和btext,然后您只需重写atext属性,使btext仍然存在,并且其值为null

这种情况下的解决方案是在情况1中使用默认值设置btext:

function dosomething1()
{
    jmodel.clear();
    jmodel.append({"atext":"hello", "btext":""}) // <----
}
函数dosomething1()
{
jmodel.clear();
jmodel.append({“atext”:“hello”,“btext”:“})/如前所述:

修改列表模型 修改列表模型可以创建和修改列表模型的内容 使用clear()、append()、set()、insert()和 setProperty()方法。例如:

Component {
    id: fruitDelegate
    Item {
        width: 200; height: 50
        Text { text: name }
        Text { text: '$' + cost; anchors.right: parent.right }

        // Double the price when clicked.
        MouseArea {
            anchors.fill: parent
            onClicked: fruitModel.setProperty(index, "cost", cost * 2)
        }
    }
} 
请注意,动态创建内容时,一旦设置了可用属性集,就无法更改。任何首先添加到模型中的属性都是模型中唯一允许的属性。

(增加重点)

初始建立属性后,不能添加或删除属性:

  • 在案例1中,您的模型最初只有atext属性,然后您希望添加btext属性,但Qt不允许

  • 在案例2中,您的模型具有属性atext和btext,然后您只需重写atext属性,使btext仍然存在,并且其值为null

这种情况下的解决方案是在情况1中使用默认值设置btext:

function dosomething1()
{
    jmodel.clear();
    jmodel.append({"atext":"hello", "btext":""}) // <----
}
函数dosomething1()
{
jmodel.clear();

append({“atext”:“hello”,“btext”:“})//非常感谢您的回答。我没有在文档中看到这句话,文档中确实解释了这一点。因为我的JSON实际上是动态的,所以我无法设置默认值,所以我每次都尝试创建一个新模型,但不确定这是否会导致泄漏。尽管如此,您的回答是正确的。非常感谢您的回答。我没有看到这一点因为我的JSON实际上是动态的,所以我无法设置默认值,所以每次我都尝试创建一个新模型,但不确定这是否会导致泄漏。尽管如此,您的答案是正确的。