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



  • 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());
    }
    @


  • Lifetime Qt Champion

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


  • Moderators

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



  • 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).



  • 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);
    @


  • Moderators

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



  • 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 );
        }
    
    }
    

    }
    @


  • Lifetime Qt Champion

    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.



  • [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....


  • Lifetime Qt Champion

    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)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.