Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-47407

Incorrect binding behavior when using binding on JS array's element

    XMLWordPrintable

Details

    Description

      I have an Item with a property. This property contains an array of JavaScript objects wich in turn contain other properties.

      When I set binding for one of object's properties to some variable and its (variable) value changes triggering the binding then all properties in the array are reset to their initial values. I've created a small demo to show the problem.

      C++ code:

      main.cpp
      #include <QGuiApplication>
      #include <QQuickWindow>
      #include <QQmlApplicationEngine>
      #include <QQmlContext>
      #include "Test.h"
      
      int main(int argc, char *argv[])
      {
          QGuiApplication app(argc, argv);
          QQmlApplicationEngine engine;
          
          Test test;
          engine.rootContext()->setContextProperty("__test__", &test);
          engine.load(QUrl(QStringLiteral("src/main.qml")));
          return app.exec();
      }
      
      Test.h
      #pragma once
      #include "QObject"
      
      class Test : public QObject
      {
          Q_OBJECT
          Q_PROPERTY(QString value READ getValue NOTIFY valueChanged)
          QString getValue(){ return ""; }
      public:
          Test(QObject* parent = 0) : QObject(parent) {}
      
      signals:
          void valueChanged();
      };
      

      QML code:

      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")
                      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")
                      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)
                  }
              }
          }
      }
      

      Here is what I get:

      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
      

      So what happens here is that after I set testObject.myArray[0].boolFlag from false to true and call test.valueChanged() method, my flag automatically resets to its initial value. Same goes for any other type used - int, string, etc.

      Attachments

        1. main.cpp
          0.4 kB
        2. main.qml
          2 kB
        3. QTBUG-47407.tar.gz
          1 kB
        4. Test.h
          0.3 kB
        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            shausman Simon Hausmann
            geniuss Hasan
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes