在 QML 中更新对 var 属性的绑定
Posted
技术标签:
【中文标题】在 QML 中更新对 var 属性的绑定【英文标题】:Update bindings to var properties in QML 【发布时间】:2015-06-17 12:16:05 【问题描述】:如果您查看this page,它会注意到当对象更改时,与 var 属性的绑定不会自动更新:
Item
property var car: new Object(wheels: 4)
Text
text: "The car has " + car.wheels + " wheels";
Component.onCompleted:
car.wheels = 6;
这将显示“汽车有 4 个***”,因为 car.wheels = 6;
不会自动触发更新。
页面没有说明如何解决这个问题?如何手动触发更新(不替换整个 car
对象)。
编辑: 明确地说,我不想替换整个 car
对象,我确实想使用 property var
(我的实际property 是一个 javascript 对象,不能存储在任何原生 QML 属性类型中)。
编辑 2:这是一个使用 QtObject
的示例,不起作用(它说“汽车有 0 个***。”:
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
ApplicationWindow
width: 640
height: 480
visible: true
property var car: QtObject property var wheels: []
Item
Text
text: "The car has " + car.wheels.length + " wheels";
Component.onCompleted:
car.wheels.push("Rear-left");
car.wheels.push("Rear-right");
car.wheels.push("Front-left");
car.wheels.push("Front-right");
【问题讨论】:
阅读this后我认为这是不可能的。但是您可以做的一件事是在数据操作后仅重新分配数组而不是整个对象:car.wheels
= car.wheels
在推送元素后。至少比替换整个对象要好。但这取决于您的数据的结构...
是的,或者我考虑添加一个虚拟属性,例如:property bool update
,然后在我的表达式中“使用”它,例如 text: "Blah blah" + (update ? "" : "")
。然后手动更新只需执行update = !update
或类似的操作。大规模的黑客攻击。
仅供参考,将car
分配回自身也适用于Component.onCompleted
块的末尾,如car = car;
【参考方案1】:
实际上,页面确实说明了如何解决这个问题:
如果 onCompleted 处理程序改为使用“car = new Object(wheels: 6)” 那么文本将被更新为“这辆车有 6 个***”,因为 汽车属性本身会发生变化,这会导致变化 发出通知。
虽然我认为这违背了您不替换整个 car
对象的要求。
话虽如此,(至少)还有一个选择——使用QtObject:
Item
property var car: QtObject property int wheels: 4
Text
text: "The car has " + car.wheels + " wheels";
Component.onCompleted:
car.wheels = 6; // This will update the text
编辑
在新示例中,如果您需要使用包含基本类型的 Javascript 数组,您列出的代码不会触发更新。但是,如果您能够使用包含 QML 类型的 list
,则可以使用以下解决方法:
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
ApplicationWindow
id: window
width: 640
height: 480
visible: true
property var car: QtObject property list<Item> wheels
Component
id: wheelComponent
QtObject
property var wheelName;
Text
anchors.fill: parent
text: "The car has " + car.wheels.length + " wheels";
Component.onCompleted:
var wheel = wheelComponent.createObject(window, "wheelName": "Rear-left" );
car.wheels += wheel;
根据您的需要,这可能会过于繁琐。创建property bool update
并在更改数组时更改它的hack 方法可能更可取。
【讨论】:
是的,我不想替换整个car
对象。而使用QtObject
只是解决了问题——您现在使用的是property int
而不是property var
。我的实际对象是一个多维矩阵,所以我必须使用property var
。
@Timmmm 即使wheels
是property var
,它也可以工作。但是,我需要查看您的多维矩阵的示例,以了解 QtObject
是否可以在这里工作。
如果wheels
是一个非对象 JS 值(即双精度或字符串),它似乎可以工作,但如果它更复杂,例如一个Array
。我在我的问题中添加了一个数组示例。顺便说一句,为帮助干杯。
@Timmmm 我已经通过答案更新了,虽然它可能无法满足您的需求。
创建一个新对象很麻烦,但是您可以通过简单地分配car = car
来触发更新通知,这应该不会创建一个新对象。【参考方案2】:
通知和自动绑定重新评估仅支持 QML 属性,不支持 JS 对象成员。
对于 var 内部的 JS 对象,只有当实际对象与另一个对象发生变化时才会触发通知,而不是当对象内部发生变化时。
但是,您可以通过在内部对象更改后手动发出 carChanged()
来强制重新评估绑定。
【讨论】:
【参考方案3】:我以这种方式解决了相同的问题:
Item
property var car: new Object(wheels: 4)
Text
Connections
target: car
onWheelsChanged:
text: "The car has " + car.wheels + " wheels";
text: "The car has " + car.wheels + " wheels";
Component.onCompleted:
car.wheels = 6;
【讨论】:
以上是关于在 QML 中更新对 var 属性的绑定的主要内容,如果未能解决你的问题,请参考以下文章