You need to understand why and when we use signals and slots (this is the third time I'm writing this in the last few weeks...). The mechanism allows to implement the so called "loosely coupled objects" paradigm (http://en.wikipedia.org/wiki/Loose_coupling). In short this means we can combine objects to function together while knowing nothing about each other. This is usually done when we have three contexts -- A, B and C. A and B know nothing of each other and C knows both A and B. This lets us to connect A and B in context C. In your situation you have just two contexts -- observer and observee (you are connecting a signal from "this") and they have to know something about each other (at least the presence of specified slots in the observer). So in the end the observee has access to a list of observers (as each has to be registered with it) and knows its interface directly. Thus instead of using signals and slots (where a signal doesn't know if anything is connected to it and what is the name of the slot(s)) you can just call specific methods directly.
void Observee::registerObserver(Observer *o) {
m_observers << o;
}
void Observee::notifySlo() {
foreach(Observer *o, m_observers) o->slo();
}
void Observee::registerObserver(Observer *o) {
m_observers << o;
}
void Observee::notifySlo() {
foreach(Observer *o, m_observers) o->slo();
}
To copy to clipboard, switch view to plain text mode
Thus no need for any QObject legacy.
On the other hand, signals and slots implements the Observer/Listener pattern itself. Thus you don't need to have any "Observer" interface nor any "Observee" interface because QObject already handles that. You can just connect signals and slots directly letting the observer decide which signals to connect to and which to ignore. Thanks to that he doesn't have to implement all those "hundreds of" slots if he's just interested in one signal. If you wish to have some control over it, you can wrap the connect statement in a function like you did but allowing the caller to specify the slot:
void Observee
::registerObserver(QObject *rcvr,
const char *slt
) { if(!connect(this, SIGNAL(sig()), rcvr, slt)){
qWarning() << "Connection failed";
}
}
// ...
x->registerObserver(this, SLOT(mySlot()));
void Observee::registerObserver(QObject *rcvr, const char *slt) {
if(!connect(this, SIGNAL(sig()), rcvr, slt)){
qWarning() << "Connection failed";
}
}
// ...
x->registerObserver(this, SLOT(mySlot()));
To copy to clipboard, switch view to plain text mode
Of course you can remove the whole registerObserver() call whatsoever and just let the caller specify both the signal and the slot.
Bookmarks