views:

407

answers:

5

We're using Qt that offers signals and slots which I find really convenient. However, with great power comes great responsibility and I think it's very easy too misuse this feature.

Are there any best-practices for signal-slot usage? I'm having a hard time to find some general guidelines in this manner. Some questions (I have clear opinions about, but that not all members of my team agree with):

  • Is it ok to use signals to report errors?
  • Is it ok to assume that a signal will be handled?
  • Can signals be used to initiate actions? E.g. signal displayInfoScreen() must be handled by a slot that shows an info screen.

Any other opinions on when signals should/shouldn't be used are very welcome!

+9  A: 

Is it ok to assume that a signal will be handled?

No it's not. Signals are fire-and-forget type of things. Who connects to a signal and what it does should not be the emitter's concern.

erelender
+2  A: 

Signals/slots (also called events) are a good way to remove coupling between objects.

For example, instead of having views that understand how the model works, and when the model changes, they "listen" to the model. The model is responsible of saying when it changes, what changes.

The problem with events is when you design your events with client requirements. For example, you should not have a signal displayInfoScreen because it assumes something about objects using this signal. Instead, it should be infoChanged and the InfoScreenDisplayer listens to this signals to display it on screen. If you need, you could add later a InfoTweeterPoster that post the info on Tweeter whenever they change.

Vincent Robert
You write a.k.a. events, but that is not true. Qt comes with a separate event infrastructure.
e8johan
+6  A: 

Signals and slots are powerful because decouples objects. You can't assume that a signal has a slot connected, as previously answered.

A major drawback of signal/slot based design is that you can very easy loose track of the logic you implemented, since one action of an object can trigger other actions of any other object that connected to a signal emitted. It is much easier to have unwanted side effects, recursive calls, etc.

Cătălin Pitiș
+4  A: 

Is it ok to use signals to report errors?

Yes, but I would generally make this situation-dependent. If the error might occur asynchronously, then a signal to indicate such is definitely proper. If the error only occurs when client code calls one certain function, then the error should be in the response from that function, not as a signal. However, there are a wide array of situations in between that might be done on a case-by-case basis.

Also, signal-slot mechanisms can make cross-thread communication easier (which might well be considered the asynchronous case), and I will use them for that purpose (error or no).

Is it ok to assume that a signal will be handled?

Signals are (philosophically) designed to indicate that something has happened. As others have indicated, it's never a good idea to assume that a signal will be matched with a slot, or even with just one other slot.

Can signals be used to initiate actions? E.g. signal displayInfoScreen() must be handled by a slot that shows an info screen.

Signals can be used to initiate actions, but probably not in the way you are thinking. The signal indicates that foo has happened. If the code monitoring your class decides that when foo happens, a dialog should be shown, then the signal was used to initiate that action. However, it's generally not the responsibility of the class emitting the signal to ensure that the proper action occurs, because it is not responsible for doing that action. (If it was, then it should be part of the same class, and no signal would be needed.)

Caleb Huitt - cjhuitt
+3  A: 

Is it ok to use signals to report
errors?

Yes, for instance, see QFtp, where the done signal carries a status. It does not carry the actual error, just information that an error has occured.

Is it ok to assume that a signal will be handled?

No. The sender can never assume that, however, your particular application can depend on it. For instance, the QAction representing File - New needs to be handled for the application to work, but the QAction object couldn't care less.

Can signals be used to initiate actions? E.g. signal displayInfoScreen() must be handled by a slot that shows an info screen.

Again, yes, for instance the QAction object. But if you want to be able to reuse components, you must be careful to ensure that the actual class does not depend on it.

e8johan
Accepted as this answer provided plain examples of uses in Qt. Do you think errors is ok, but only when the processing is asynchronous?
larsm
Thanks! And, yes, otherwise, add either a status return value, or a status argument (as QString::toInt does).
e8johan