qt - 在数组元素上使用绑定(bind)时出现奇怪的绑定(bind)行为

标签 qt visual-studio-2013 qml qtquick2 qt5.5

我有一个带有属性的 Item。此属性包含一个 JavaScript 对象数组,而这些对象又包含其他属性。

当我将对象的一个​​属性绑定(bind)到某个变量并且它的(变量)值更改触发绑定(bind)时,数组中的所有属性都将重置为它们的初始值。 我创建了一个小演示来展示这个问题。

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] : Set testObject.myArray[0] to TRUE qml: CLICK #1[RED SQUARE] : DONE

qml: CLICK #2[BLUE SQUARE] : Triggering notify by calling C++ <Test::valueChanged> method

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].boolFlagfalse 设置为 true 并调用 test.valueChanged() 方法,我的标志自动重置为初始值。同样适用于任何其他使用的类型 - intstring 等。

为什么会这样?

Visual Studio 已安装更新 4。

最佳答案

非常棘手,但这是 QML 的预期行为。您遇到的是绑定(bind)分配与程序分配的冲突,这是 QML 的常见缺陷。

首先,您已经设置了一个到 myArray 的绑定(bind)(实际上)表示任何时候 __test__.value 更改,重新分配一个文字数组给 我的数组。稍后您通过程序修改该数组来破坏该绑定(bind)。请记住,文字数组实际上是 JavaScript 代码,每次在绑定(bind)中触发信号时都会对其求值。

因此,您在最后一个 console.log 中看到的不是 bool 已恢复,而是整个 myArray 已重置为新值,从绑定(bind)重建。

您真正想要的是一个新的 bool 属性,您可以将其分配给该属性,并且您的文字数组会绑定(bind)到该属性。像这样:

property bool myBoolFlag: false
property var myArray : [{
        name : "CustomName" + __test__.value,
        boolFlag : myBoolFlag
    }]

然后,当您分配给 myBoolFlag 时,数组将被重建。当您触发 valueChanged 时,数组也会被重建,但这次 bool 值是从属性中提取的并具有正确的值。

关于qt - 在数组元素上使用绑定(bind)时出现奇怪的绑定(bind)行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31536574/

相关文章:

visual-studio-2013 - 使用 Web Essentials 2013 将 Compass 集成到 Visual Studio 2013 update 2

visual-studio-2013 - VS2013中的工具箱和服务器资源管理器窗口在哪里?

c++ - 在 Qt 中如何将模态对话框窗口转换为非模态对话框窗口?

c++ - Qt/C++ 在不使用 dynamic_cast 的情况下将 QGraphicsItem 转换为自定义 QGraphicsItem

git - Visual Studio 在连接时使用 TFS GIT 错误

Qt Quick QML MouseArea 按下时自动重复

qt - 如何在键盘上仅显示带有 qt 的数字

javascript - 如何在 QML 中集成 Javascript 库 (socketio)?

c++ - QWebView/Qt WebKit 不会打开一些 SSL 页面;不允许重定向?

c++ - 在 C++ 应用程序中使用 id3lib 库时出现 undefined reference 链接器错误