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

QML bindings don't run for C++ BINDABLEs

    XMLWordPrintable

Details

    Description

      A Q_PROPERTY() without being BINDABLE can be initialized with a binding from QML.  But one that is BINDABLE cannot, it simply remains uninitialized. Below is a simple test that I did with int and QObject* as the property types...

      C++ class with properties.  There are four total, two of each type where one is BINDABLE and the other isn't: 

      #ifndef MYTYPE_HPP
      #define MYTYPE_HPP
      
      #include <QBindable>
      #include <QDebug>
      #include <QObject>
      
      class MyType : public QObject
      {
          Q_OBJECT
          Q_DISABLE_COPY(MyType)
          Q_PROPERTY(int      debug1 READ getDebug1 WRITE setDebug1 NOTIFY debug1Changed)
          Q_PROPERTY(int      debug2 READ getDebug2 WRITE setDebug2 NOTIFY debug2Changed BINDABLE bindableDebug2)
          Q_PROPERTY(QObject* debug3 READ getDebug3 WRITE setDebug3 NOTIFY debug3Changed)
          Q_PROPERTY(QObject* debug4 READ getDebug4 WRITE setDebug4 NOTIFY debug4Changed BINDABLE bindableDebug4)
      signals:
          void debug1Changed() const;
          void debug2Changed() const;
          void debug3Changed() const;
          void debug4Changed() const;
      public:
          QBindable<int>      bindableDebug2() const { return QBindable<int>      (&_debug2); }
          QBindable<QObject*> bindableDebug4() const { return QBindable<QObject *>(&_debug4); }
          int      getDebug1() const { qDebug() << "Get debug1" << _debug1; return _debug1; }
          int      getDebug2() const { qDebug() << "Get debug2" << _debug2; return _debug2; }
          QObject* getDebug3() const { qDebug() << "Get debug3" << _debug3; return _debug3; }
          QObject* getDebug4() const { qDebug() << "Get debug4" << _debug4; return _debug4; }
          void setDebug1(int      debug1) { qDebug() << "Set debug1" << _debug1 << "->" <<        debug1; if (debug1 != _debug1) { _debug1 = debug1; emit debug1Changed(); } }
          void setDebug2(int      debug2) { qDebug() << "Set debug2" << _debug2 << "->" <<        debug2; if (debug2 != _debug2) { _debug2 = debug2; emit debug2Changed(); } }
          void setDebug3(QObject* debug3) { qDebug() << "Set debug3" << _debug3 << "->" << (void*)debug3; if (debug3 != _debug3) { _debug3 = debug3; emit debug3Changed(); } }
          void setDebug4(QObject* debug4) { qDebug() << "Set debug4" << _debug4 << "->" << (void*)debug4; if (debug4 != _debug4) { _debug4 = debug4; emit debug4Changed(); } }
      private:
          int _debug1{0};
          Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(MyType, int, _debug2, 0, &MyType::debug2Changed)
          QObject* _debug3{nullptr};
          Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(MyType, QObject*, _debug4, nullptr, &MyType::debug4Changed)
      public:
          explicit MyType(QObject *parent = nullptr) : QObject{parent} {};
      };
      
      #endif // MYTYPE_HPP
      

       
      Creating an instance of MyType and attempt to assign a binding to each. Once initialization is over, log the value for each of them.

      Unable to find source-code formatter for language: qml. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
          MyType {
              debug1: { console.log(`Binding for debug1 = ${10}`);   return 10; }
              debug2: { console.log(`Binding for debug2 = ${10}`);   return 10; }
              debug3: { console.log(`Binding for debug3 = ${this}`); return this; }
              debug4: { console.log(`Binding for debug4 = ${this}`); return this; }
      
              Component.onCompleted: {
                  console.log(`Starting value for debug1 = ${debug1}`);
                  console.log(`Starting value for debug2 = ${debug2}`);
                  console.log(`Starting value for debug3 = ${debug3}`);
                  console.log(`Starting value for debug4 = ${debug4}`);
              }
          }
      

      This is the output. Only debug1 and debug3 were set by their binding. The bindings for debug2 and debug4 weren't even attempted.

      qml: Binding for debug1 = 10
      Set debug1 0 -> 10
      qml: Binding for debug3 = MyType(0x563e0aa24d60)
      Set debug3 0x0 -> 0x563e0aa24d60
      Get debug1 10
      qml: Starting value for debug1 = 10
      Get debug2 0
      qml: Starting value for debug2 = 0
      Get debug3 MyType(0x563e0aa24d60)
      qml: Starting value for debug3 = MyType(0x563e0aa24d60)
      Get debug4 0x0
      qml: Starting value for debug4 = null
      

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            fabiankosmale Fabian Kosmale
            solim Mark Domschot
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes