Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

    [Solved] QObject::setProperty does not fire the appropriate signal

    General and Desktop
    4
    10
    3422
    Loading More Posts
    • 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.
    • M
      MichelS last edited by

      Hey guys,

      I've defined a property like this:

      @
      Q_PROPERTY(int keepAliveInterval READ keepAliveInterval WRITE setKeepAliveInterval NOTIFY keepAliveIntervalChanged)
      @

      And now I set the property using the QObject::setProperty -Method as described here http://qt-project.org/doc/qt-5.0/qtcore/qobject.html#setProperty

      But that does not seem to fire the keepAliveIntervalChanged signal as I'd expect.

      How can I fire that signal?

      Background:
      What I'm trying to achieve is this:
      Read a JSON-file with property settings, convert that to an QVariantMap, for each item:
      apply that value to the property and fire the signal.

      This works so far, but no signal is fired....
      @
      QVariantMap::const_iterator iter;
      for (iter = variants.constBegin(); iter != variants.constEnd(); ++iter) {
      int pIdx = metaobject->indexOfProperty( iter.key().toLatin1() );

      if ( pIdx < 0 ) {
      continue;
      }
      object->setProperty(iter.key().toLatin1(), iter.value());
      }
      @

      1 Reply Last reply Reply Quote 0
      • SGaist
        SGaist Lifetime Qt Champion last edited by

        Hi,

        Qt can't know when to trigger the signal (it's your business logic).

        Your setter can be something like:

        @
        void MyClass::setKeepAliveInterval(int interval)
        {
        if (_interval != interval) {
        _interval = interval;
        // do the needed stuff
        emit keepAliveIntervalChanged(_interval)
        }
        }
        @

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply Reply Quote 0
        • raven-worx
          raven-worx Moderators last edited by

          did you specify the signal in your class definition?
          what did the connect statement return?

          --- 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 Reply Quote 0
          • D
            dbzhang800 last edited by

            Hi, you have mis-understanded the usage and function of Q_PROPERTY.

            It won't fire signal for you automatically, you must emit the signal (keepAliveIntervalChanged) manually in you set function (setKeepAliveInterval).

            1 Reply Last reply Reply Quote 0
            • M
              MichelS last edited by

              Oh yes I forgot about that. You are right 1+1=2 and SGaist
              Of course my setter fires the signal if it's called.
              But the setter does not seem to be called.

              and to raven-worx:
              Yes, the connection is OK, cause I used the compiler checked connection style

              @
              connect(systemConfig(), &SystemConfiguration::keepAliveIntervalChanged, NetworkService::instance(), &NetworkService::setKeepAliveInterval);
              @

              1 Reply Last reply Reply Quote 0
              • raven-worx
                raven-worx Moderators last edited by

                please make sure that iter.key().toLatin1() returns "keepAliveInterval" and also that setProperty() returns true...meaning the right property is set.

                --- 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 Reply Quote 0
                • M
                  MichelS last edited by

                  I checked the property afterwards and it's updated.

                  But anyway. I finally found a solution, by manually fire the signal.

                  @
                  void QObjectHelper::qvariant2qobject(const QVariantMap& variants, QObject* object)
                  {
                  const QMetaObject *metaobject = object->metaObject();

                  QVariantMap::const_iterator iter;
                  for (iter = variants.constBegin(); iter != variants.constEnd(); ++iter) {
                      int pIdx = metaobject->indexOfProperty( iter.key().toLatin1() );
                  
                      if ( pIdx < 0 ) {
                          continue;
                      }
                      QByteArray propertyName = iter.key().toLatin1();
                      object->setProperty(propertyName, iter.value());
                  
                      QMetaProperty metaproperty = metaobject->property( pIdx );
                      QVariant::Type type = metaproperty.type();
                      QVariant v( iter.value() );
                      if ( v.canConvert( type ) ) {
                          v.convert( type );
                          metaproperty.write( object, v );
                          if (metaproperty.hasNotifySignal()) {
                              QGenericArgument ga(v.typeName(),v.data());
                              metaproperty.notifySignal().invoke(object, Qt::QueuedConnection, ga);
                          }
                      } else if (QString(QLatin1String("QVariant")).compare(QLatin1String(metaproperty.typeName())) == 0) {
                          metaproperty.write( object, v );
                      }
                  
                  }
                  

                  }
                  @

                  1 Reply Last reply Reply Quote 0
                  • SGaist
                    SGaist Lifetime Qt Champion last edited by

                    Did you do the checks suggested by raven-worx ?

                    I am using setProperty and it all works well.

                    Also, if your setter follows the pattern of my previous post, the signal won't be fired when setting the same value.

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply Reply Quote 0
                    • M
                      MichelS last edited by

                      [quote author="SGaist" date="1372417858"]Did you do the checks suggested by raven-worx ?[/quote]
                      Yes, the result is true und the iter.key().toLatin1() returns “keepAliveInterval”

                      [quote author="SGaist" date="1372417858"]Also, if your setter follows the pattern of my previous post, the signal won't be fired when setting the same value.[/quote]
                      Wow!! That was the hint...
                      Sometimes the solution is just too easy.
                      Embarrassing....

                      1 Reply Last reply Reply Quote 0
                      • SGaist
                        SGaist Lifetime Qt Champion last edited by

                        No biggies, this can happen to anyone (was bitten by something like this because the initial value of a member was the same as the one saved in settings so nothing happened)

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post