我有Item
有财产。此属性包含一个JavaScript对象数组,而这些对象又包含其他属性。
当我将某个对象属性的绑定设置为某个变量并且其(变量)值更改触发绑定时,数组中的所有属性都将重置为其初始值。 我已经创建了一个小型演示来展示问题。
C ++代码:
// main.cpp
#include <QGuiApplication>
#include <QQuickWindow>
#include <QQmlApplicationEngine>
#include <QQmlContext>
class Test : public QObject
{
Q_OBJECT
Q_PROPERTY(QString value READ value NOTIFY valueChanged)
public:
Test(QObject* parent = 0) : QObject(parent) {}
QString value() const { return ""; }
Q_SIGNAL void valueChanged();
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
Test test;
engine.rootContext()->setContextProperty("__test__", &test);
engine.load(QUrl(QStringLiteral("qrc:/ui/main.qml")));
return app.exec();
}
#include "main.moc"
QML代码:
// main.qml
import QtQuick 2.4
import QtQuick.Controls 1.3
ApplicationWindow {
id: container
visible: true
width: 640
height: 480
property int clicksCounter: 0
Item {
id: testObject
property var myArray : [{
name : "CustomName" + __test__.value,
boolFlag : false
}]
}
Rectangle {
x: 10
y: 10
width: 100
height: 100
color: "red"
MouseArea {
anchors.fill: parent
onClicked: {
container.clicksCounter++
console.log("CLICK #" + container.clicksCounter + "[RED SQUARE] : Set testObject.myArray[0] to TRUE\n")
testObject.myArray[0].boolFlag = true
console.log("CLICK #" + container.clicksCounter + "[RED SQUARE] : DONE\n")
}
}
}
Rectangle {
x: 120
y: 10
width: 100
height: 100
color: "blue"
MouseArea {
anchors.fill: parent
onClicked: {
container.clicksCounter++
console.log("CLICK #" + container.clicksCounter + "[BLUE SQUARE] : Triggering notify by calling C++ <Test::valueChanged> method \n")
console.log("CLICK #" + container.clicksCounter + "[BLUE SQUARE] : [BEFORE] testObject.myArray[0].name: " + testObject.myArray[0].name + ', testObject.myArray[0].boolFlag: ' + testObject.myArray[0].boolFlag)
__test__.valueChanged()
console.log("CLICK #" + container.clicksCounter + "[BLUE SQUARE] : [AFTER] testObject.myArray[0].name: " + testObject.myArray[0].name + ', testObject.myArray[0].boolFlag: ' + testObject.myArray[0].boolFlag)
}
}
}
}
这是我得到的:
qml:CLICK#1 [RED SQUARE]:将testObject.myArray [0]设置为TRUE qml: 点击#1 [RED SQUARE]:完成
qml:CLICK#2 [BLUE SQUARE]:通过调用C ++触发通知 &lt;试验::的valueChanged&GT;方法
qml:CLICK#2 [BLUE SQUARE]:[BEFORE] testObject.myArray [0] .name: CustomName,testObject.myArray [0] .boolFlag:true qml:CLICK#2 [BLUE SQUARE]:[AFTER] testObject.myArray [0] .name:CustomName, testObject.myArray [0] .boolFlag:false
所以这里发生的是,在我将testObject.myArray[0].boolFlag
从false
设置为true
并调用test.valueChanged()
方法之后,我的标志会自动重置为其初始值。使用的任何其他类型也是如此 - int
,string
等。
为什么会这样?
Visual Studio安装了更新4。
答案 0 :(得分:0)
非常棘手,但这是QML的预期行为。您所遭受的是绑定任务与程序分配之间的冲突,这是QML的常见缺陷。
首先,您已设置绑定到myArray
(实际上)说任何时候__test__.value
更改,重新将文字数组分配给myArray
。然后通过程序修改该数组来破坏该绑定。请记住,文字数组实际上是每次信号在绑定中触发时都要评估的JavaScript代码。
所以,你在上一个console.log中看到的并不是bool已经被恢复,而是整个myArray被重置为一个新值,从绑定重建。
您真正想要的是可以分配给的新bool属性,并且您的文字数组将绑定到此属性。像这样:
property bool myBoolFlag: false
property var myArray : [{
name : "CustomName" + __test__.value,
boolFlag : myBoolFlag
}]
然后,当您分配给myBoolFlag
时,阵列会重建。当你解雇valueChanged
时,数组也会被重建,但这次bool值是从属性中提取的,并且具有正确的值。