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);
|
label, &QLabel::setText);
|
||||||
//! [48]
|
//! [48]
|
||||||
|
|
||||||
|
//! [49]
|
||||||
|
if (isSignalConnected(QMethaMethod::fromSignal(&MyObject::valueChanged))) {
|
||||||
|
QByteArray data;
|
||||||
|
data = get_the_value(); // expensive operation
|
||||||
|
emit valueChanged(data);
|
||||||
|
}
|
||||||
|
//! [49]
|
||||||
|
|
||||||
//! [meta data]
|
//! [meta data]
|
||||||
//: This is a comment for the translator.
|
//: This is a comment for the translator.
|
||||||
//= qtn_foo_bar
|
//= qtn_foo_bar
|
||||||
|
@ -2157,13 +2157,12 @@ int QObject::senderSignalIndex() const
|
|||||||
|
|
||||||
\snippet code/src_corelib_kernel_qobject.cpp 21
|
\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
|
\warning This function violates the object-oriented principle of
|
||||||
modularity. However, it might be useful when you need to perform
|
modularity. However, it might be useful when you need to perform
|
||||||
expensive initialization only if something is connected to a
|
expensive initialization only if something is connected to a
|
||||||
signal.
|
signal.
|
||||||
|
|
||||||
|
\sa isSignalConnected()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int QObject::receivers(const char *signal) const
|
int QObject::receivers(const char *signal) const
|
||||||
@ -2209,6 +2208,60 @@ int QObject::receivers(const char *signal) const
|
|||||||
return receivers;
|
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
|
\internal
|
||||||
|
|
||||||
|
@ -365,6 +365,7 @@ protected:
|
|||||||
QObject *sender() const;
|
QObject *sender() const;
|
||||||
int senderSignalIndex() const;
|
int senderSignalIndex() const;
|
||||||
int receivers(const char* signal) const;
|
int receivers(const char* signal) const;
|
||||||
|
bool isSignalConnected(const QMetaMethod &signal) const;
|
||||||
|
|
||||||
virtual void timerEvent(QTimerEvent *);
|
virtual void timerEvent(QTimerEvent *);
|
||||||
virtual void childEvent(QChildEvent *);
|
virtual void childEvent(QChildEvent *);
|
||||||
|
@ -3774,6 +3774,7 @@ public:
|
|||||||
void tst_QObject::isSignalConnected()
|
void tst_QObject::isSignalConnected()
|
||||||
{
|
{
|
||||||
ManySignals o;
|
ManySignals o;
|
||||||
|
const QMetaObject *meta = o.metaObject();
|
||||||
o.rec = 0;
|
o.rec = 0;
|
||||||
#ifdef QT_BUILD_INTERNAL
|
#ifdef QT_BUILD_INTERNAL
|
||||||
QObjectPrivate *priv = QObjectPrivate::get(&o);
|
QObjectPrivate *priv = QObjectPrivate::get(&o);
|
||||||
@ -3784,6 +3785,13 @@ void tst_QObject::isSignalConnected()
|
|||||||
QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig29()")));
|
QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig29()")));
|
||||||
QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig60()")));
|
QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig60()")));
|
||||||
#endif
|
#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(sig00()), &o, SIGNAL(sig69()));
|
||||||
QObject::connect(&o, SIGNAL(sig34()), &o, SIGNAL(sig03()));
|
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("sig69()")));
|
||||||
QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig18()")));
|
QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig18()")));
|
||||||
#endif
|
#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(sig18()), &o, SIGNAL(sig29()));
|
||||||
QObject::connect(&o, SIGNAL(sig29()), &o, SIGNAL(sig62()));
|
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("sig69()")));
|
||||||
QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig27()")));
|
QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig27()")));
|
||||||
#endif
|
#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);
|
QCOMPARE(o.rec, 0);
|
||||||
emit o.sig01();
|
emit o.sig01();
|
||||||
@ -3845,6 +3870,12 @@ void tst_QObject::isSignalConnected()
|
|||||||
QCOMPARE(o.rec, 2);
|
QCOMPARE(o.rec, 2);
|
||||||
emit o.sig36();
|
emit o.sig36();
|
||||||
QCOMPARE(o.rec, 2);
|
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()
|
void tst_QObject::qMetaObjectConnect()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user