列出由JavaScript数据模型实时驱动的委托

时间:2016-08-22 16:12:04

标签: qt qml qtquick2

我有一个QML应用程序,我正在创建从JavaScript接收的元素列表。使用this answer中的详细信息我将模型填充为JS数组,并且效果很好。但是,我喜欢它,以便当JavaScript对象的属性发生变化时,从它们驱动的ListView项目会更新。

这是一个显示问题的简单测试应用程序。 ListView已正确填充显示正确ID /标题的MyRow个实例,但当计时器更改rand属性时,列行未更改(显示0 }为最后一项)。

MyRow.qml

import QtQuick 2.0
import QtQuick.Layouts 1.3

Rectangle {
    property var obj
    color:'#eeeeff'; height:20
    RowLayout {
        anchors.fill:parent
        Text { text:obj.id                           }
        Text { text:obj.title; Layout.fillWidth:true }
        Text { text:obj.rand                         }
    }
}

main.qml

import QtQuick 2.7
import QtQuick.Window 2.2

Window {
    id:app; visible:true; width:200; height:100

    property var database: ({"17":"World","42":"Hello"})
    property var objById:  ({})

    function getObj(id){
        if (!objById[id]) objById[id] = { id:id, title:database[id], rand:0 };
        return objById[id];
    }

    ListView {
        id:mylist
        anchors.fill:parent
        model: [42,17] // object ids
        delegate: MyRow {
            width:parent.width
            obj:getObj(mylist.model[index])
        }
    }

    Timer { // Update every object's rand value every second
        interval:1000; running:true; repeat:true
        onTriggered: {
            Object.keys(objById).forEach(function(id){
                objById[id].rand = Math.random()*100<<0;
            })
        }
    }
}

当对象的属性发生变化时,如何让委托的Text项更新文本?

1 个答案:

答案 0 :(得分:1)

使属性绑定正常工作的最简单(唯一?)方法是创建真正的Qt对象来挂钩值。如果您不想使用ListModel(因为您希望使用主库中的项快速填充模型),则可以使用createObject()生成对象并将其传递给您的委托。

以下是根据需要运行的更新main.qml

Window {
    // ...same as above...
    Component { // Creates real Qt objects with bindable properties
        id:objFactory
        QtObject {
            property int    id
            property string title
            property int    rand:0
        }
    }

    function getObj(id){
        if (!objById[id])
            objById[id] = objFactory.createObject( app, {id:id,title:database[id]} );
        return objById[id];
    }
    // ...same as above...
}

此外,您可能希望将property var obj中的MyRow.qml更改为更具体的property QtObject obj(或更具体的对象类型,具体取决于您传入的内容)。

最后请注意,使用modelData而不是mylist.model[index]会更简洁/更简单:

ListView {
    anchors.fill:parent
    model: [42,17] // object ids
    delegate: MyRow {
        width:parent.width
        obj:getObj(modelData)
    }
}