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

Strange behaviour with Q_OBJECT_BINDABLE_PROPERTY and std::unique_ptr

    XMLWordPrintable

Details

    • Suggestion
    • Resolution: Unresolved
    • Not Evaluated
    • None
    • None
    • Core: Object Model
    • None

    Description

      I have the following class in foo.h:

      class Foo : public QObject
      {
          Q_OBJECT
          Q_PROPERTY(int x READ x WRITE setX NOTIFY xChanged BINDABLE bindableX)
          Q_PROPERTY(int * p READ getP  NOTIFY pChanged BINDABLE bindableP)
      public:
          explicit Foo(QObject *parent = nullptr);
      
          int x() const { return xProp; }
          void setX(int x) { xProp = x; emit xChanged();}
          QBindable<int> bindableX() { return QBindable<int>(&xProp); }
      
          int * getP() const { return p.value().get(); }
          void setP(std::unique_ptr<int> x) { p = std::move(x); emit pChanged();}
          QBindable<const std::unique_ptr<int>&> bindableP() { return QBindable<const std::unique_ptr<int>&>(&xProp); }
      
      signals:
          void xChanged();
          void pChanged();
      
      private:
          Q_OBJECT_BINDABLE_PROPERTY(Foo, int, xProp, &Foo::xChanged)
          Q_OBJECT_BINDABLE_PROPERTY(Foo, std::unique_ptr<int>, p, &Foo::pChanged)
      };
      

      This is my main.cpp:

      int main(int argc, char *argv[])
      {
          Foo f;
          auto b = f.bindableP().subscribe([&]{
              qDebug() << "pointer changed to" <<f.getP() ;
          });
          auto b2 = f.bindableX().subscribe([&]{
              qDebug() << "x changed to" <<f.x() ;
          });
          QProperty<int> test;
          test.setBinding([&]{
              auto p =f.getP();
              if(p)
                  return *p * 2;
              return -1;
          });
          auto ts = test.subscribe([&](){qDebug() << "test is now" << test;});
          f.setP(std::make_unique<int>(20));
          f.setX(4);
          qDebug() << "test";
          f.setP(std::make_unique<int>(30));
          f.setX(5);
          qDebug() << "test";
          return 0;
      }
      

      With this code the output looks as expected:

      pointer changed to 0x0
      x changed to 0
      test is now -1
      test is now 40
      x changed to 4
      pointer changed to 0x560411674010
      test
      test is now 60
      x changed to 5
      pointer changed to 0x560411675090
      test
      

      BUT: If I remove the 'f.setX(4)' in the main.cpp I get the following:

      pointer changed to 0x0
      x changed to 0
      test is now -1
      test is now 40
      test
      test is now 60
      x changed to 5
      pointer changed to 0x559910401090
      test
      

      The 'pointer changed to ...' output is missing. But the test variable was recomputed correctly.
      PS: The output does not change if I remove the 'emit ...' calls
      PS 2: If I remove the signal from the std::unique_ptr<int> property, I get compile errors.
      PS 3: The QProperty system is very cool! I would love to see a blog post about how the 'dependency detection' word. In my example: How does the 'test' QProperty knows that it depends on the QBindings of the std::unique_ptr. Awesome work!

      Attachments

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

        Activity

          People

            thiago Thiago Macieira
            autoantwort autoantwort
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes