From a6892d69281d3555f3c3fd03f3b3892b1940191d Mon Sep 17 00:00:00 2001 From: John Brooks Date: Thu, 12 Aug 2010 10:14:28 +0200 Subject: Added QObject::senderSignalIndex() Returns the metamethod index of the signal executing the current slot Merge-request: 2433 Reviewed-by: Bradley T. Hughes --- src/corelib/kernel/qobject.cpp | 43 +++++++++++++++++++++++++++++++++++++- src/corelib/kernel/qobject.h | 1 + tests/auto/qobject/tst_qobject.cpp | 24 +++++++++++++++++++-- 3 files changed, 65 insertions(+), 3 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 9ce111d..ceffa66 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -2287,7 +2287,7 @@ static void err_info_about_objects(const char * func, a thread different from this object's thread. Do not use this function in this type of scenario. - \sa QSignalMapper + \sa senderSignalIndex(), QSignalMapper */ QObject *QObject::sender() const @@ -2307,6 +2307,47 @@ QObject *QObject::sender() const } /*! + \since 4.8 + + Returns the meta-method index of the signal that called the currently + executing slot, which is a member of the class returned by sender(). + If called outside of a slot activated by a signal, -1 is returned. + + For signals with default parameters, this function will always return + the index with all parameters, regardless of which was used with + connect(). For example, the signal \c {destroyed(QObject *obj = 0)} + will have two different indexes (with and without the parameter), but + this function will always return the index with a parameter. This does + not apply when overloading signals with different parameters. + + \warning This function violates the object-oriented principle of + modularity. However, getting access to the signal index might be useful + when many signals are connected to a single slot. + + \warning The return value of this function is not valid when the slot + is called via a Qt::DirectConnection from a thread different from this + object's thread. Do not use this function in this type of scenario. + + \sa sender(), QMetaObject::indexOfSignal(), QMetaObject::method() +*/ + +int QObject::senderSignalIndex() const +{ + Q_D(const QObject); + + QMutexLocker locker(signalSlotLock(this)); + if (!d->currentSender) + return -1; + + for (QObjectPrivate::Connection *c = d->senders; c; c = c->next) { + if (c->sender == d->currentSender->sender) + return d->currentSender->signal; + } + + return -1; +} + +/*! Returns the number of receivers connected to the \a signal. Since both slots and signals can be used as receivers for signals, diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index 21bad16..b5db936 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -280,6 +280,7 @@ public Q_SLOTS: protected: QObject *sender() const; + int senderSignalIndex() const; int receivers(const char* signal) const; virtual void timerEvent(QTimerEvent *); diff --git a/tests/auto/qobject/tst_qobject.cpp b/tests/auto/qobject/tst_qobject.cpp index fc38a84..abfe24b 100644 --- a/tests/auto/qobject/tst_qobject.cpp +++ b/tests/auto/qobject/tst_qobject.cpp @@ -1782,9 +1782,12 @@ class SuperObject : public QObject Q_OBJECT public: QObject *theSender; + int theSignalId; + SuperObject() { theSender = 0; + theSignalId = 0; } friend class tst_QObject; @@ -1795,16 +1798,17 @@ public slots: void rememberSender() { theSender = sender(); + theSignalId = senderSignalIndex(); } void deleteAndRememberSender() { delete theSender; - theSender = sender(); + rememberSender(); } signals: + void anotherSignal(); void theSignal(); - }; void tst_QObject::sender() @@ -1812,12 +1816,23 @@ void tst_QObject::sender() { SuperObject sender; SuperObject receiver; + connect(&sender, SIGNAL(anotherSignal()), + &receiver, SLOT(rememberSender())); connect(&sender, SIGNAL(theSignal()), &receiver, SLOT(rememberSender())); QCOMPARE(receiver.sender(), (QObject *)0); + QCOMPARE(receiver.senderSignalIndex(), -1); emit sender.theSignal(); QCOMPARE(receiver.theSender, (QObject *)&sender); QCOMPARE(receiver.sender(), (QObject *)0); + QCOMPARE(receiver.theSignalId, + sender.metaObject()->indexOfSignal("theSignal()")); + QCOMPARE(receiver.senderSignalIndex(), -1); + + emit sender.anotherSignal(); + QCOMPARE(receiver.theSignalId, + sender.metaObject()->indexOfSignal("anotherSignal()")); + QCOMPARE(receiver.senderSignalIndex(), -1); } { @@ -1834,11 +1849,16 @@ void tst_QObject::sender() Qt::DirectConnection); QCOMPARE(receiver->sender(), (QObject *)0); + QCOMPARE(receiver->senderSignalIndex(), -1); receiver->theSender = 0; + receiver->theSignalId = -1; thread.start(); emit sender->theSignal(); QCOMPARE(receiver->theSender, (QObject *) sender); QCOMPARE(receiver->sender(), (QObject *)0); + QCOMPARE(receiver->theSignalId, + sender->metaObject()->indexOfSignal("theSignal()")); + QCOMPARE(receiver->senderSignalIndex(), -1); QVERIFY(thread.wait(10000)); delete receiver; -- cgit v0.12