diff options
author | Olivier Goffart <ogoffart@woboq.com> | 2012-04-24 15:01:47 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-05-02 10:59:41 +0200 |
commit | bcd477e0bc48bb028193d7707d1ecfbd61b5bdc1 (patch) | |
tree | 5b34c02f76c4e9c8b3aeb7eec6fc69ac3b864e24 /src | |
parent | ade888860334d207f5f070b0bc9c4c98deaf3862 (diff) |
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>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp | 8 | ||||
-rw-r--r-- | src/corelib/kernel/qobject.cpp | 59 | ||||
-rw-r--r-- | src/corelib/kernel/qobject.h | 1 |
3 files changed, 65 insertions, 3 deletions
diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp index 2367bfd724..95c54169ce 100644 --- a/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp @@ -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 diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index e0dc5bcd9d..49a9beb298 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -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 @@ -2210,6 +2209,60 @@ int QObject::receivers(const char *signal) const } /*! + \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 This helper function calculates signal and method index for the given diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index d840d9184f..5e969d67f6 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -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 *); |