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