PDA

View Full Version : Signals and Slots question



Thoosle
4th December 2006, 08:13
Docs say "Signals and slots are loosely coupled: A class which emits a signal neither knows nor cares which slots receive the signal". What if that was not what was desired? What if you had an emitting class that was to send messages to some arbitrary number of widgets. Say it was a socket class receiving messages over a lan and the messages were addressed each to go to some particular widget and you wanted the message passed using signals/slots. As each widget is created the signal/slot connection is setup and the widget then awaits possible incoming messages. What I don't see is how "emit" could be used to emit to a particular widget. From what I'm reading in the docs, it seems like there really isn't a way to place the burdon on the "emitter" to send things only to one target. Instead, when it emits it emits to all targets(widgets) and it's the widgets responsibility to decide if the message is meant for it? I hope I'm making sense....I can see how to connect a signal to many slots. Like connecting a number of wires from one source to many widgets. This serves the purpose of making the connections. But, I don't want to send a message to a widget that it wasn't intended for. My conundrum is that I don't see how to use signals/slots "connect" and/or "emit" syntax to do this????

wysota
4th December 2006, 08:43
What I don't see is how "emit" could be used to emit to a particular widget.
It can't be used this way directly. Signals are public.


From what I'm reading in the docs, it seems like there really isn't a way to place the burdon on the "emitter" to send things only to one target. Instead, when it emits it emits to all targets(widgets) and it's the widgets responsibility to decide if the message is meant for it?
Correct. You can help yourself by using a QSignalMapper


But, I don't want to send a message to a widget that it wasn't intended for.
Don't use signals and slots then. Just register objects in the "emitter" and call its methods directly from the emitter.


My conundrum is that I don't see how to use signals/slots "connect" and/or "emit" syntax to do this????
You don't have to force using signals and slots everywhere


Emitter emitter;
Receiver rcv1, rcv2, rcv3;
emitter.register(&rcv1);
emitter.register(&rcv2);
emitter.register(&rcv3);
//...

void Emitter::emitMessage(int id, const QString &msg){
Receiver *rcv = _registered[id]; // QMap<int, Receiver*>
rcv->receive(msg);
}

Thoosle
4th December 2006, 16:39
wysota, thanks for the insight and guidance, very helpful.

Thoosle
4th December 2006, 18:32
wysota, When I look at the docs for QSignalMapper I believe here llies the solution to the problem I was describing. Apparently, when a widget is created I can set a mapping to it from the "emitter" based on the widgets id so that signals from the "emitter" are mapped to the appropriate widget. I will "connect" to all the widgets but only send messages to their intended destination, which is the desired operation. In the QSignalMapper "Detailed Description" it examples using QSignalMapper to setmappings for a group of buttons to signal a slot with eachs buttons text id thus bundling the buttons signals. What I'm wanting to do is like the inverse of that. Do you agree my conclusions in this or have I missed the point? BTW, I'm thinking that the "emitter" and widgets will run in their own threads, hence the desire for signals/slots. Thanks again for your insights....

wysota
4th December 2006, 22:33
QSignalMapper does a many-to-one mapping and as you said, you want the opposite. The code I've written in the previous post more or less does exactly that. It just isn't thread safe, so if you wish to use threads for your receivers, you need to modify it. I would even suggest to use custom events instead of signals and slots, this way instead of rcv->receive(...) you'd simply call QCoreApplication::postEvent(rcv, new MessageEvent(...)). Then it's just a matter of reimpementing customEvent() to handle the event and implementing the custom event class (MessageEvent).

Thoosle
5th December 2006, 00:24
wysota, this discussion is most helpful and enlightening for me. I'll take a look at your suggestions. Again, thanks very much for your insights....