Introduce QObject::isSignalConnected(QMetaMethod)
This is much more performant than calling QObject::receivers(const char*) Can be used instead of connectNotify in some cases. Change-Id: I19e0933f678f171f515d9a0f69f0ad4fb7d894b4 Reviewed-by: Kent Hansen <kent.hansen@nokia.com>
This commit is contained in:
parent
ade8888603
commit
bcd477e0bc
@ -479,6 +479,14 @@ QObject::disconnect(lineEdit, &QLineEdit::textChanged,
|
||||
label, &QLabel::setText);
|
||||
//! [48]
|
||||
|
||||
//! [49]
|
||||
if (isSignalConnected(QMethaMethod::fromSignal(&MyObject::valueChanged))) {
|
||||
QByteArray data;
|
||||
data = get_the_value(); // expensive operation
|
||||
emit valueChanged(data);
|
||||
}
|
||||
//! [49]
|
||||
|
||||
//! [meta data]
|
||||
//: This is a comment for the translator.
|
||||
//= qtn_foo_bar
|
||||
|
@ -2157,13 +2157,12 @@ int QObject::senderSignalIndex() const
|
||||
|
||||
\snippet code/src_corelib_kernel_qobject.cpp 21
|
||||
|
||||
As the code snippet above illustrates, you can use this function
|
||||
to avoid emitting a signal that nobody listens to.
|
||||
|
||||
\warning This function violates the object-oriented principle of
|
||||
modularity. However, it might be useful when you need to perform
|
||||
expensive initialization only if something is connected to a
|
||||
signal.
|
||||
|
||||
\sa isSignalConnected()
|
||||
*/
|
||||
|
||||
int QObject::receivers(const char *signal) const
|
||||
@ -2209,6 +2208,60 @@ int QObject::receivers(const char *signal) const
|
||||
return receivers;
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 5.0
|
||||
Returns true if the \a signal is connected to at least one receiver,
|
||||
otherwise returns false.
|
||||
|
||||
\a signal must be a signal member of this object, otherwise the behaviour
|
||||
is undefined.
|
||||
|
||||
\snippet code/src_corelib_kernel_qobject.cpp 21
|
||||
|
||||
As the code snippet above illustrates, you can use this function
|
||||
to avoid emitting a signal that nobody listens to.
|
||||
|
||||
\warning This function violates the object-oriented principle of
|
||||
modularity. However, it might be useful when you need to perform
|
||||
expensive initialization only if something is connected to a
|
||||
signal.
|
||||
*/
|
||||
bool QObject::isSignalConnected(const QMetaMethod &signal) const
|
||||
{
|
||||
Q_D(const QObject);
|
||||
if (!signal.mobj)
|
||||
return false;
|
||||
|
||||
Q_ASSERT_X(signal.mobj->cast(this) && signal.methodType() == QMetaMethod::Signal,
|
||||
"QObject::isSignalConnected" , "the parametter must be a signal member of the object");
|
||||
uint signalIndex = (signal.handle - QMetaObjectPrivate::get(signal.mobj)->methodData)/5;
|
||||
|
||||
if (signal.mobj->d.data[signal.handle + 4] & MethodCloned)
|
||||
signalIndex = QMetaObjectPrivate::originalClone(signal.mobj, signalIndex);
|
||||
|
||||
int signalOffset;
|
||||
int methodOffset;
|
||||
computeOffsets(signal.mobj, &signalOffset, &methodOffset);
|
||||
signalIndex += signalOffset;
|
||||
|
||||
if (signalIndex < sizeof(d->connectedSignals) * 8)
|
||||
return d->isSignalConnected(signalIndex);
|
||||
|
||||
QMutexLocker locker(signalSlotLock(this));
|
||||
if (d->connectionLists) {
|
||||
if (signalIndex < uint(d->connectionLists->count())) {
|
||||
const QObjectPrivate::Connection *c =
|
||||
d->connectionLists->at(signalIndex).first;
|
||||
while (c) {
|
||||
if (c->receiver)
|
||||
return true;
|
||||
c = c->nextConnectionList;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
|
||||
|
@ -365,6 +365,7 @@ protected:
|
||||
QObject *sender() const;
|
||||
int senderSignalIndex() const;
|
||||
int receivers(const char* signal) const;
|
||||
bool isSignalConnected(const QMetaMethod &signal) const;
|
||||
|
||||
virtual void timerEvent(QTimerEvent *);
|
||||
virtual void childEvent(QChildEvent *);
|
||||
|
@ -3774,6 +3774,7 @@ public:
|
||||
void tst_QObject::isSignalConnected()
|
||||
{
|
||||
ManySignals o;
|
||||
const QMetaObject *meta = o.metaObject();
|
||||
o.rec = 0;
|
||||
#ifdef QT_BUILD_INTERNAL
|
||||
QObjectPrivate *priv = QObjectPrivate::get(&o);
|
||||
@ -3784,6 +3785,13 @@ void tst_QObject::isSignalConnected()
|
||||
QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig29()")));
|
||||
QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig60()")));
|
||||
#endif
|
||||
QVERIFY(!o.isSignalConnected(meta->method(meta->indexOfSignal("destroyed()"))));
|
||||
QVERIFY(!o.isSignalConnected(meta->method(meta->indexOfSignal("sig00()"))));
|
||||
QVERIFY(!o.isSignalConnected(meta->method(meta->indexOfSignal("sig05()"))));
|
||||
QVERIFY(!o.isSignalConnected(meta->method(meta->indexOfSignal("sig15()"))));
|
||||
QVERIFY(!o.isSignalConnected(meta->method(meta->indexOfSignal("sig29()"))));
|
||||
QVERIFY(!o.isSignalConnected(meta->method(meta->indexOfSignal("sig60()"))));
|
||||
QVERIFY(!o.isSignalConnected(meta->method(meta->indexOfSignal("sig69()"))));
|
||||
|
||||
QObject::connect(&o, SIGNAL(sig00()), &o, SIGNAL(sig69()));
|
||||
QObject::connect(&o, SIGNAL(sig34()), &o, SIGNAL(sig03()));
|
||||
@ -3802,6 +3810,18 @@ void tst_QObject::isSignalConnected()
|
||||
QVERIFY(priv->isSignalConnected(priv->signalIndex("sig69()")));
|
||||
QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig18()")));
|
||||
#endif
|
||||
QVERIFY(!o.isSignalConnected(meta->method(meta->indexOfSignal("destroyed()"))));
|
||||
QVERIFY(!o.isSignalConnected(meta->method(meta->indexOfSignal("destroyed(QObject*)"))));
|
||||
QVERIFY(!o.isSignalConnected(meta->method(meta->indexOfSignal("sig05()"))));
|
||||
QVERIFY(!o.isSignalConnected(meta->method(meta->indexOfSignal("sig15()"))));
|
||||
QVERIFY(!o.isSignalConnected(meta->method(meta->indexOfSignal("sig29()"))));
|
||||
|
||||
QVERIFY(o.isSignalConnected(meta->method(meta->indexOfSignal("sig00()"))));
|
||||
QVERIFY(o.isSignalConnected(meta->method(meta->indexOfSignal("sig03()"))));
|
||||
QVERIFY(o.isSignalConnected(meta->method(meta->indexOfSignal("sig34()"))));
|
||||
QVERIFY(o.isSignalConnected(meta->method(meta->indexOfSignal("sig69()"))));
|
||||
QVERIFY(!o.isSignalConnected(meta->method(meta->indexOfSignal("sig18()"))));
|
||||
|
||||
|
||||
QObject::connect(&o, SIGNAL(sig18()), &o, SIGNAL(sig29()));
|
||||
QObject::connect(&o, SIGNAL(sig29()), &o, SIGNAL(sig62()));
|
||||
@ -3815,6 +3835,11 @@ void tst_QObject::isSignalConnected()
|
||||
QVERIFY(priv->isSignalConnected(priv->signalIndex("sig69()")));
|
||||
QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig27()")));
|
||||
#endif
|
||||
QVERIFY(o.isSignalConnected(meta->method(meta->indexOfSignal("sig18()"))));
|
||||
QVERIFY(o.isSignalConnected(meta->method(meta->indexOfSignal("sig62()"))));
|
||||
QVERIFY(o.isSignalConnected(meta->method(meta->indexOfSignal("sig28()"))));
|
||||
QVERIFY(o.isSignalConnected(meta->method(meta->indexOfSignal("sig69()"))));
|
||||
QVERIFY(!o.isSignalConnected(meta->method(meta->indexOfSignal("sig27()"))));
|
||||
|
||||
QCOMPARE(o.rec, 0);
|
||||
emit o.sig01();
|
||||
@ -3845,6 +3870,12 @@ void tst_QObject::isSignalConnected()
|
||||
QCOMPARE(o.rec, 2);
|
||||
emit o.sig36();
|
||||
QCOMPARE(o.rec, 2);
|
||||
|
||||
QObject::connect(&o, &QObject::destroyed, qt_noop);
|
||||
QVERIFY(o.isSignalConnected(meta->method(meta->indexOfSignal("destroyed()"))));
|
||||
QVERIFY(o.isSignalConnected(meta->method(meta->indexOfSignal("destroyed(QObject*)"))));
|
||||
|
||||
QVERIFY(!o.isSignalConnected(QMetaMethod()));
|
||||
}
|
||||
|
||||
void tst_QObject::qMetaObjectConnect()
|
||||
|
Loading…
Reference in New Issue
Block a user