Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. How to make a connection to Component destruction() signal from cpp side
Forum Updated to NodeBB v4.3 + New Features

How to make a connection to Component destruction() signal from cpp side

Scheduled Pinned Locked Moved Solved QML and Qt Quick
8 Posts 2 Posters 2.7k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • E Offline
    E Offline
    Eligijus
    wrote on last edited by
    #1

    Hello,

    Connecting Component destruction() signal to cpp slot from qml side is quite simple - Component.onDestruction: mySlot().

    But I'm intrested how to catch this signal or make a connection from cpp side.

    raven-worxR 1 Reply Last reply
    0
    • E Eligijus

      Hello,

      Connecting Component destruction() signal to cpp slot from qml side is quite simple - Component.onDestruction: mySlot().

      But I'm intrested how to catch this signal or make a connection from cpp side.

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by
      #2

      @Eligijus
      since a QQuickItem inherits QObject simply connect to QObject::destroyed() signal

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      E 1 Reply Last reply
      0
      • raven-worxR raven-worx

        @Eligijus
        since a QQuickItem inherits QObject simply connect to QObject::destroyed() signal

        E Offline
        E Offline
        Eligijus
        wrote on last edited by
        #3

        @raven-worx Component destruction() signal is emited when object property values are still valid/not destroyed. As I still want to access some property data from this object, both QObject::destroyed() and ~QObject() get called too late.

        raven-worxR 1 Reply Last reply
        0
        • E Eligijus

          @raven-worx Component destruction() signal is emited when object property values are still valid/not destroyed. As I still want to access some property data from this object, both QObject::destroyed() and ~QObject() get called too late.

          raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by raven-worx
          #4

          @Eligijus
          The problem is that the attached property of Component (private QQmlComponentAttached class) hooks directly into the QML engine internals.
          Deleting an item from C++ always has the "drawback" that the derived destructor is called first (due to the virtual destructor of QObject).
          So i would expect that the Component.onDestruction only works for QML items with QML ownership.

          About what items are we actually talking? Whats the use case exactly?

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          E 1 Reply Last reply
          0
          • raven-worxR raven-worx

            @Eligijus
            The problem is that the attached property of Component (private QQmlComponentAttached class) hooks directly into the QML engine internals.
            Deleting an item from C++ always has the "drawback" that the derived destructor is called first (due to the virtual destructor of QObject).
            So i would expect that the Component.onDestruction only works for QML items with QML ownership.

            About what items are we actually talking? Whats the use case exactly?

            E Offline
            E Offline
            Eligijus
            wrote on last edited by
            #5

            @raven-worx My use case is that I want to save property array value to file upon destruction.
            Let's say I have Class Test

            class Test : public QObject
            {
                Q_OBJECT
            public:
                explicit Test(QObject *parent = nullptr);
                ~Test();
            
                Q_INVOKABLE void store();
            };
            

            store method for simplicity currently prints value to debug console

            void Test::store()
            {
                const QMetaObject *o = metaObject();
                int offset = o->propertyOffset();
                int count = o->propertyCount();
            
                for (int i = offset; i < count; ++i) {
                    QMetaProperty metaProperty = o->property(i);
                    QVariant defaultValue = property(metaProperty.name());
            
                    if (defaultValue.userType() == qMetaTypeId<QJSValue>())
                        defaultValue = defaultValue.value<QJSValue>().toVariant();
            
                    qDebug() << metaProperty.name() << defaultValue;
                }
            }
            

            I create Test in qml:

            Test {
                    id: t
                    property var foo: [100, 200, 300]
                }
            

            And if store() is called in constructor here's the output:

            foo QVariant(Invalid)
            

            But if I connect store() to Component destruction() in qml I get my expected output:

            foo QVariant(QVariantList, (QVariant(int, 100), QVariant(int, 200), QVariant(int, 300)))
            

            My problem is that I don't want to add additional code to qml side and make a connection from cpp side because there are many Test objects created in qml.

            raven-worxR 1 Reply Last reply
            0
            • E Eligijus

              @raven-worx My use case is that I want to save property array value to file upon destruction.
              Let's say I have Class Test

              class Test : public QObject
              {
                  Q_OBJECT
              public:
                  explicit Test(QObject *parent = nullptr);
                  ~Test();
              
                  Q_INVOKABLE void store();
              };
              

              store method for simplicity currently prints value to debug console

              void Test::store()
              {
                  const QMetaObject *o = metaObject();
                  int offset = o->propertyOffset();
                  int count = o->propertyCount();
              
                  for (int i = offset; i < count; ++i) {
                      QMetaProperty metaProperty = o->property(i);
                      QVariant defaultValue = property(metaProperty.name());
              
                      if (defaultValue.userType() == qMetaTypeId<QJSValue>())
                          defaultValue = defaultValue.value<QJSValue>().toVariant();
              
                      qDebug() << metaProperty.name() << defaultValue;
                  }
              }
              

              I create Test in qml:

              Test {
                      id: t
                      property var foo: [100, 200, 300]
                  }
              

              And if store() is called in constructor here's the output:

              foo QVariant(Invalid)
              

              But if I connect store() to Component destruction() in qml I get my expected output:

              foo QVariant(QVariantList, (QVariant(int, 100), QVariant(int, 200), QVariant(int, 300)))
              

              My problem is that I don't want to add additional code to qml side and make a connection from cpp side because there are many Test objects created in qml.

              raven-worxR Offline
              raven-worxR Offline
              raven-worx
              Moderators
              wrote on last edited by raven-worx
              #6

              @Eligijus
              Try this approach:

              if( QObject *attached = qmlAttachedPropertiesObject<QQmlComponent>(this, true) )
                   connect( attached, SIGNAL(destruction()), this, SLOT(store()) ); // explicitly using the old syntax here, since QQmlComponentAttached is a private type
              

              Note the qmlAttachedPropertiesObject() call with the second parameter set to true to create the attached object if it doesn't exist yet.

              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
              If you have a question please use the forum so others can benefit from the solution in the future

              E 1 Reply Last reply
              3
              • raven-worxR raven-worx

                @Eligijus
                Try this approach:

                if( QObject *attached = qmlAttachedPropertiesObject<QQmlComponent>(this, true) )
                     connect( attached, SIGNAL(destruction()), this, SLOT(store()) ); // explicitly using the old syntax here, since QQmlComponentAttached is a private type
                

                Note the qmlAttachedPropertiesObject() call with the second parameter set to true to create the attached object if it doesn't exist yet.

                E Offline
                E Offline
                Eligijus
                wrote on last edited by
                #7

                @raven-worx That works. Thanks for answer and comment why use an old connect sytax there very informative.
                I ended up putting this code snippet inside componentComplete() method inherited from QQmlParserStatus because putting it directly in constructor didn't work.

                raven-worxR 1 Reply Last reply
                0
                • E Eligijus

                  @raven-worx That works. Thanks for answer and comment why use an old connect sytax there very informative.
                  I ended up putting this code snippet inside componentComplete() method inherited from QQmlParserStatus because putting it directly in constructor didn't work.

                  raven-worxR Offline
                  raven-worxR Offline
                  raven-worx
                  Moderators
                  wrote on last edited by
                  #8

                  @Eligijus said in How to make a connection to Component destruction() signal from cpp side:

                  Thanks for answer and comment why use an old connect sytax there very informative.

                  Just to point out the alternative to the old connect syntax:
                  the connection could also be done by searching for the corresponding QMetaMethod in the QMetaObject of the attached object and connect it.
                  But it's way shorter with the old syntax.

                  --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                  If you have a question please use the forum so others can benefit from the solution in the future

                  1 Reply Last reply
                  2

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved