Qt signals and slots - are they intended only for the graphical interface or for the entire architecture of the application?

I'm really curious - are these Qt signals and slots (delegate-patter?) Designed for GUI callbacks only, or are they great for the whole application? I mean, is it better to split the application into small, stand-alone objects (classes) and combine them through signals and slots. And if so, what is the recommended way to return a value from a signal (a request signal that is used to return something), since the values ​​of the returned Qt signals are ignored.

+4
source share
6 answers

QT signals and slots are not intended to return values ​​from the receiver. They are strictly one way of communication.

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

As for using it for anything other than the GUI, you can use them wherever it fits, if it fits. Why highlight the GUI as something special?

+7
source

You can use them for everything.

They work great for network code for instnce

+2
source

Signals and slots were created to simulate the exchange of messages between an object at the library level (since C ++ does not support messages such as Smalltalk), so you can use them anywhere you want objects to communicate with each other (or transmit some data around or activate something ... etc.). I used them for almost every thing and they worked perfectly, the only problem I encountered was parallel code, where I had several threads exchanging with each other using signals and slots, it was very bad (I need real-time message processing), because slot execution was not immediate.

I do not think that you can use signals to return a value (and should not) call signals to transfer data to other objects

/ * if you have, you want to decide to try to explain it possibly, there is a way to solve the problem * /.

+2
source

The implementation of the signal and slot from Qt is quite flexible. This is certainly not limited to GUI elements. There is even a separate transmission mechanism in turn, which allows you to transmit signals from one stream to another.

If you really think what you need, you can pass a link or pointer inside the signal, this will allow you to transfer information back to the radiating object. But I will be careful with reading the signals and the execution of the corresponding slots. There are two modes of separation and execution of the signal at the receivers, which are in close proximity and in line. If you signal the order of flows, it will be required, and then immediately emit.

In practice, I noticed that large networks connecting to the signal and slot can be a little cumbersome to debug, because now you create a separate structure from the output and containment of the object.

+1
source

In particular, in response to the return values, I did not feel that the Qt signals and the slot create a good mechanism for moving back and forth. As others have noted, they work great in the observer / role structure. If you think about it, there are potential problems with return values ​​... for example, what happens when you have more than one slot connected to a signal and each of them returns different values? The same problems arise in the SigC ++ and Boost :: Signals libraries, where everyone has a mechanism (another?) To handle this, or at least figure out what you get.

If you really need to return a value, there are two relatively good ways I've found to manage it. First, use the Qt event mechanism to query the data, and then pass the requested data in response. Note that events do not have a built-in way to execute responses, so you will need to extend QEvent to be able to handle this case. We really do this in numbers of applications at my work. It works well enough for a threaded application when you need an asynchronous mechanism. The disadvantage of this method is that the requestor must know about the object with which he is requesting data (to send an event). The response object does not need to know more than the request, and how to send a 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 an object that should be able to request data. This works much better with a good abstract functor library that allows you to encapsulate objects and functions, such as the aforementioned SigC ++ or Boost :: Signals. It is also well suited for situations where an immediate response is required - you run a functor statement and it returns a value before continuing with the function. It also allows you to write an object similar to how you would do with a signal / slot mechanism, where an object that needs a return value from a function (signal) does not need to know anything about where the functor (signal connection) did or has come. It just starts the functor as needed.

+1
source

All Articles