There is a function QObject::sender(), than, when invoked in a slot, provides the QObject* pointer to the sending object.
It's behaviour is far less useful if you have the following structure.
class A : public QObject { Q_OBJECT
...
signals:
void foo();
};
class B : public QObject { Q_OBJECT
...
signals:
void foo();
};
class C : public QObject { Q_OBJECT
...
public slots:
void bar() { qDebug() << sender(); }
};
A a;
B b;
C c;
connect(&A, SIGNAL(foo()), &B, SIGNAL(foo()));
connect(&B, SIGNAL(foo()), &C, SLOT(bar()));
A::whatever() { emit foo(); }
C::bar() indicates B as the emitter. How can I get the original emitting object, without dealing with all the relays?
Unfortunately QObject::sender() is protected so this naive approach in C::bar() wouldn't compile (not sure if it ever could work, but that's my only idea to traverse the sender() backwards):
QObject *ptr = this;
while ((ptr = ptr->sender()) != NULL)
qDebug() << ptr->objectName();
To answer some of the questions raised in comments:
A- custom widget (lots of dynamically created ones) (holding some data, pointers, whatnot)B- custom top-level UI element (member of theQStackedWidget, handles some UI responsibilities)C- (in practice,C1,C2,C3) - work that needs to be performed (using common state, such as DSP queue) on data stored in As.
Ultimately, A needs to know very little about Cs (or even if anything cares about it's signals). B is where the UI aggregation takes place (also the top-level UI calls Cs to set DSP parameters etc). Cs need to know if sender() is qobject_cast'able to IA interface.
It can be reworked to something along the lines of:
class A : public QObject { Q_OBJECT
...
signals:
void foo(QObject*);
};
class B : public QObject { Q_OBJECT
...
signals:
void foo(QObject*);
};
class C : public QObject { Q_OBJECT
...
public slots:
void bar(QObject* mySender) { qDebug() << mySender; }
};
A a;
B b;
C c;
connect(&A, SIGNAL(foo(QObject*)), &B, SIGNAL(foo(QObject*)));
connect(&B, SIGNAL(foo(QObject*)), &C, SLOT(bar(QObject*)));
A::whatever() { emit foo(this); }