Qt QML为什么这个ListView和ListModel没有意义?

时间:2019-07-05 20:49:31

标签: qt listview qml listmodel

我遇到一个ListView和一个简单的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()
    {
        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”将不会更改它。

但是

先按“计划B”将说出“ hello world”,然后按“计划A”和“计划B”将在“ hello world”和“ hello”之间切换。

它不应该依赖于首先按下哪个按钮,而是每次都要清除模型。

我已经在Qt5.12.3和5.9上进行了尝试,并且没有变化。

更新

在@eyllanesc回答之后,我已经更新了我的代码以代替为每次更新创建一个新模型。这行得通,但我不知道我现在是否有内存泄漏。

这是我的代码:

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();
        }
    }



}

1 个答案:

答案 0 :(得分:0)

the docs指出:

  

修改列表模型

  修改列表模型可以创建ListModel的内容并   使用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)
        }
    }
} 
     

请注意,动态创建内容时,一组可用属性无法更改。首先添加到模型的任何属性都是模型中唯一允许的属性。

(添加了重点)

在最初建立属性后,您无法添加或删除属性:

  • 在第一种情况下,您的模型最初仅具有atext属性,然后要添加btext属性,但Qt不允许。

  • 在第2种情况下,您的模型具有atext和btext属性,则只需重写atext属性,以便btext仍然存在并且值为null。

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

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