views:

523

answers:

6

Hello.

I'm very curious - are Qt's signals and slots (delegate patter?) intended only for GUI callback or they are perfectly fine and intended for entire app? I mean, is it better to split app into small, self-contained objects (classes) and interconnect them via signals and slots. And if so, what is the recommended way to return value from a signal (request-like signal that is used to return something) since Qt's signals return values are ignored.

+2  A: 

You can use them for everything.

They work very well for networking code for instnce

Martin Beckett
And what about a recommended method for one object to get value from another via signal?
Eye of Hell
@Eye of Hell: Just send it as the signal parameter, i.e. push the data from the source object to the destination object
blwy10
+4  A: 

QT's signals and slots are not intended for returning values from the reciver. They are a strictly one way communication mechanism.

The receiver may actually be in a completely different thread, receiving the signal from a queue, way after the sender emit call returned.

As for using it for anything other than GUI.. you can use them for wherever it fit, if it fits there. why single out GUI as something special?

shoosh
I'm interested in your personal experience :). Never so a Qt program where non-gui classes was interconnected via signals and slots. Normally they just take pointers to each other and use direct method calls. Maybe it's some reasons about it?
Eye of Hell
passing pointers around creates a strong coupling between classes which is usually undesirable. You can read alot about the observer design pattern all over the google.
shoosh
@Eye of Hell: See Martin Beckett's response. A lot of Qt other than GUI uses signals and slots, especially for networking
blwy10
+2  A: 

Signals and Slots were made to simulate messaging between object at the library level (cause C++ does not support messages like Smalltalk does), so you can use them any where you want to make objects communicate to each other (either to pass some data around or to activate something ... etc ). I have used them almost for every thing and they worked fine the only problem I got was with concurrent code where I had multiple threads communicating with each others using signal and slots it was really bad (I needed a real time processing of messages) because the execution of the slot was not immediate.

I don't think that you can use signals to return a value (and you shouldn't) cause signals are made to send data over to other objects

/* if you have specific problem that you want to solve try to explain it maybe there is a way around to solve it */.

Ayoub
+4  A: 

Signal and Slots are a way to implement the observer pattern. Anywhere you use the observer pattern (e.g. to reduce coupling), you can use signals and slots as well.

Tobias Langner
+1  A: 

The signal and slot implementation from Qt is fairly flexible. It is definitely not limited to GUI elements. There is even a separate queued signal passing mechanism that lets you pass signals from one thread to the other.

If you really think you need to you can pass a reference or pointer inside the signal, this lets you pass information back to the emitting object. But I would be careful with read up on signals and when the corresponding slots are executed. There are two modes on signal emission and execution on the receivers, immediate and queued. If you are signaling across threads queuing would be required and then emit returns immediately.

In practice I have noticed that large networks of signal and slot connection can get a little bit unwieldy to debug as you are now creating a separate structure from the object derivation and containment.

Harald Scheirich
+1  A: 

Specifically in response to the return values, I haven't felt that Qt's signals and slot make a good back-and-forth mechanism. As the others have mentioned, they work very well in the observer pattern/role. If you think about it, there are potential problems with the return values... such as what happens when you have more than one slot connected to a signal, and they each return different values? The same problems occur in the SigC++ and Boost::Signals libraries, where each has a (different?) mechanism to deal with it, or at least figure out what you'd be getting.

If you really need a return value, there are two relatively nice ways I've found to manage it. The first is to use Qt's event mechanism to request data, then pass the requested data back as a response. Note that the events don't have a built-in way to do responses, so you would need extend QEvent to be able to handle this case. We actually do this a fair amount in the applications at my job. It works quite well for a threaded application, when you need the asynchronous mechanism. The drawback to this method is that the requestor needs to know about the object it is requesting data from (in order to send the event). The responding object doesn't need to know any more than the request and how to send back the response, which is usually encoded into the request. Note that this is almost the opposite of the observer pattern.

The second method is to pass a functor object to the object that needs to be able to request data. This works a lot better with a good abstract functor library that lets you encapsulate objects and functions, such as the aforementioned SigC++ or Boost::Signals. This also works well for situations where you want an immediate response -- you run the functor's operator, and it returns a value before you continue processing in the function. This also allows you to write an object similar to how you would with the signal/slot mechanism, where the object that needs the return value from the function (signal) doesn't need to know anything about where the functor (signal's connection) was made, or came from. It just runs the functor as necessary.

Caleb Huitt - cjhuitt
And what bout direct connection between signal and slot and pass a pointer to variable?
Eye of Hell
@Eye of Hell: The problem with an object passing a pointer to a variable in a signal is that it can't know that a slot will be hooked up using a direct connection. You may certainly do that, and provide "outside" knowledge that asserts it must be so, but there is no way for the class itself to verify that. If it somehow ends up not being a direct connection, then you will have an error in your program, and not easily be able to find out why. You also still have the problem of multiple slots connected to the signal -- which one provides the return value?
Caleb Huitt - cjhuitt
Thanks for clearing that. Still no silver bullet, :).
Eye of Hell