列出由 JavaScript 数据模型实时驱动的委托
List delegates driven live by JavaScript data model
我有一个 QML 应用程序,我在其中创建从 JavaScript 接收到的元素列表。使用 this answer 中的详细信息,我将模型填充为 JS 数组,效果很好。但是,我希望这样当 JavaScript 对象的属性发生变化时,由它们驱动的 ListView 项目会实时更新。
这是一个显示问题的简单测试应用程序。 ListView
正确填充了 MyRow
个实例,显示正确的 id/title,但是当计时器更改 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
项更新其文本?
使 属性 绑定正常工作的最简单(唯一?)方法是创建真正的 Qt 对象来挂钩值。如果您不想使用 ListModel
(because you want to quickly populate a model with items from a master library), then you can use 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...
}
此外,您可能希望将 MyRow.qml
中的 property var obj
更改为更具体的 property QtObject obj
(或更具体的对象类型,具体取决于您传入的内容)。
最后,请注意,使用 modelData
而不是 mylist.model[index]
稍微 cleaner/simpler:
ListView {
anchors.fill:parent
model: [42,17] // object ids
delegate: MyRow {
width:parent.width
obj:getObj(modelData)
}
}
我有一个 QML 应用程序,我在其中创建从 JavaScript 接收到的元素列表。使用 this answer 中的详细信息,我将模型填充为 JS 数组,效果很好。但是,我希望这样当 JavaScript 对象的属性发生变化时,由它们驱动的 ListView 项目会实时更新。
这是一个显示问题的简单测试应用程序。 ListView
正确填充了 MyRow
个实例,显示正确的 id/title,但是当计时器更改 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
项更新其文本?
使 属性 绑定正常工作的最简单(唯一?)方法是创建真正的 Qt 对象来挂钩值。如果您不想使用 ListModel
(because you want to quickly populate a model with items from a master library), then you can use 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...
}
此外,您可能希望将 MyRow.qml
中的 property var obj
更改为更具体的 property QtObject obj
(或更具体的对象类型,具体取决于您传入的内容)。
最后,请注意,使用 modelData
而不是 mylist.model[index]
稍微 cleaner/simpler:
ListView {
anchors.fill:parent
model: [42,17] // object ids
delegate: MyRow {
width:parent.width
obj:getObj(modelData)
}
}