Actually I have been using signals and slots while programing in Qt.
The main use of signals and slots are in the UI interaction, for example a clicked button sends a signal that will invoke a slot to perform action.
I know that it's possible to use signals and slots for non-gui application, for example a server side application.
I looked for other libraries that offers signal and slots and I found boost library. It's some how different from what I learned from Qt.
And then I was wondering what's the real utility of signals and slots, since I can manually call a function to perform an action at a given time.
for example in boost here is an example of signals/slots :
#include <boost/signals2.hpp>
#include <iostream>
void mySlot(){
std::cout << "I'm a slot" << std::endl;
}
void main(){
boost::signals2::signal<void ()> sig;
// Connecting the slot to the signal.
sig.connect(mySlot);
// Emitting a signal that will call mySlot
sig();
return 0;
}
I could simply do the same thing with a simple call of mySlot() isn't it ?
Not that what made me think is that when we try to connect two different slots, they are called in the same order than connection. and if the first slot is blocking ( try to add an infinite loop) the second slots will never be called ! I guess that it's a kind of vector that stores the addresses of the functions and then iterate the loop and call one by one !
What's the magic behind the signals and slots ? or it's only a kind of abstraction for the developer ?
Thank you in advance.
In short: The main idea is decoupling in my opinion.
In longer: With direct function calls, you could not have a well-separate establishment between the common functionality and the clients of it, for instance. There would be a tight coupling unlike with signals and slots because you would need to know at the point of some condition meeting your criteria which methods exactly to call.
If you would like to gain more freedom, like with many other OOP design patterns, you need something like signals and slots. When a common component, let us call it a library, emits a signal, it does not have to be aware of the (potentially not-yet-existing) client interfaces. This makes the common component flexible enough.
It will also keep responsiveness of the application better since it is not a direct call, but processed by the Qt event loop. Arguably, you could circumvent this with custom threading mechanisms, but that would be lotta more work to make it safe enough, and you would end up doing something close this in the end of the day.
Signals and slots are simply a communication mechanism that can be used across different threads of execution. That is the main value (especially in a GUI focussed library such as QT). Usually there is 1 thread responsible for drawing and managing the graphical side of the application and 1 or more worker threads. Using signals and slots it is possible to abstract away from this. If you wanted to use direct function calls you'd need to synchronise the threads which would lead to reduced performance and responsiveness on the GUI side.
Indeed within one execution thread it does not make much sense using signals and slots. The value comes in when you want to communicatie between processes (on the same machine or between different machines).
Related
I am creating simple online chat with server and client in one application. I wrote client-side, but i don't know how will be correct use QTcpServer.
Need i create QTcpServer in new thread? So that I can connect to it as a client from this application. If yes, how do it? Or it's useless and not needed idea?
Need i create new thread for every new connection in order to process it?
I am developing a chat as a course project for a university
Assuming you are using Qt's networking APIs, you don't need to use multiple threads. The reason is that Qt's APIs are designed around a non-blocking event-loop model, so it is expected that no function-call should ever take more than a negligible amount of time (e.g. a few milliseconds) to return, after which the main thread's QEventLoop resumes execution and can therefore handle other tasks in a timely manner, all from within a single thread.
That said, there are a few optional methods in the Qt API that are blocking, and in a single-threaded application, calling those methods risks making your application un-responsive for (however long it takes for those methods to return). Fortunately those methods aren't necessary, and they are clearly documented. I recommend avoiding them, as there are always better, non-blocking ways to achieve the same result in Qt, e.g. by connecting the appropriate signals to the appropriate slots.
To sum up: threads aren't necessary in Qt-based networking, and your program will be simpler, more reliable, and easier to debug if you don't use threads. When implementing server-like functionality, a QTcpServer object is useful; you might want to have a look at this example program for cues on how to use it.
I've earned experience in C++ but I'm new at Qt. I was given a real project to work on, developed by someone that doesn't work for this company any longer. I don't know if it is a good practice and I apologize in advance for the terminology that might well not be adedcquate: I noticed that this project is literally full of signals/slots pairs that I deem unnecessary. More precisely: the classes that dictate the logic of the applications see each other, it would be sufficient to expose some public methods to trigger the desired procedures but, nevertheless, this is almost always achieved using signals and slots (and I say it again here: even when no input from GUI occurs). Given that I'm a newby in Qt, is it a good practice to do so? Thanks.
Edit: the cases that I reported don't encompass signals coming from timers, threads or whatever. This guy used signals and slots pairs like if it was a substitution for direct method call from class, say, A to class B
Overuse of signals and slots is a very bad and unfortunately very common practice. It hides dependencies, it makes code hard to debug and basically unmaintainable in the long term. Unfortunately many programmers think this it is a good practice because they achieve "decoupling", which seems as a holy grail to them. This is a nonsense.
I do not say you should not use signals and slots at all. I only say you should not overuse them. Signals and slots are the perfect tool to implement Observer design pattern to have a "reactive" system in which objects react to other objects having changed their states. Only this is the correct use of signals and slots. Almost every other use of signals and slots is wrong. The most extreme case which I have seen was implementing a getter function with a signal-slot connection. The signal sent a reference to a variable and the slot filled it with a value and then it returned to the emitter. This is just mad!
How you know that your signals and slots implement Observer pattern correctly? These are rules of thumb which follow from my quite long experience with Qt:
The nature of the signal is that the emitter announces publicly (signals are always public - except if you use a private class dummy parameter) by sending out some signal that its state has somehow changed.
The emitter does not care who are the observers or whether there are any observers at all, i.e. the emitter must not depend on observers in any way.
It is never the emitter's responsibility to establish or manage the connection - do not ever do it! The connection/disconnection is the responsibility of the observer (then it often connects to a private slot) or of some parent object which knows of the existence of both, the emitter and the observer (in that case the mutual parent connects emitter's signal to observers public slot).
It is normal that you will see lots of signal-slot connections in GUI layer and this is perfectly OK (note: GUI layer includes view models!). This is because GUI is typically a reactive system where objects react to other objects or to some changes in the underlying layers. But you will probably see much less signal-slot connections in the business logic layer (btw. in many projects business logic is coded without using Qt).
Regarding naming: I have encountered an interesting code smell. When the observer's public (!) slot is called like onSomethingHappened() - with emphasis on the prefix on. This is almost always sign of bad design and abuse of signals and slots. Usually this slot should be a) made private and the connection should be established by the observer or b) should be renamed to doSomething() or c) should be renamed and should be called as normal method instead of using signals and slots.
And a note about why overuse of signals and slots are hard to maintain. There are many potential problems in the long term which can break your code:
The dependencies with signals and slots are often hidden in a distant seemingly unrelated part of code. This relates to the signal-slot abuse when emitter actually depends on the observer but this is not clear when looking at the emitter's code. If your class depends on some other class/module, this dependency should be explicit and clearly visible.
When signals and slots are connected and then disconnected programmatically by your code, you often end up in state when you forgot do disconnect and you now have multiple connections. Having multiple connections is often overlooked because it often does not do any harm, it only makes the code somewhat slower, i.e. changed text is updated multiple times instead of once only - nobody will catch this issue unless you have a thousand-fold connection. these multiplying connections are somewhat similar to memory leaks. Small memory leaks remain often unnoticed, which is similar to multiple connections.
It often happens that you depend on the order in which the connections are established. And when these order-dependent connections are established in distant parts of code, you are in bad trouble, this code will fall apart sooner or later.
To check whether I do not have multiple connections or whether the connection/disconnection was successful, I am using these my helper utils https://github.com/vladimir-kraus/qtutils/blob/main/qtutils/safeconnect.h
PS: In the text above I am using term "emitter" (emits the signal) and "observer" (observes the emitter and receives the signal). Sometimes people use "sender" and "receiver" instead. My intention was to emphasize the fact that the emitter emits a signals without actually knowing whether anyone receives it. The word "sender" gives the impression that you send the signal to someone, which is however exactly the cause of signal-slot overuse and bad design. So using "sender" only leads to confusion, IMO. And by using "observer" I wanted to emphasize that signals and slots are the tool to implement the Observer design pattern.
PPS: Signals and slots are also the perfect tool for async communicating between threads in Qt. This use case may be one of the very few exceptions to the principles which I described above.
It depends of course, but mostly yes, it's a correct practice because it keeps object decoupled. Two classes which sees each other does not means they can use each other if they're not in a relation of master-slave o don't follow a logical hierarchy. Mostly you will couple everything in a non-reversible way in a result of flipper-effect of calls. The proof could be you want to fix that "making methods public" which may breaks incapsulation and contract of a class, which may lead to bad design choice non dependant from using Qt.
Since we're not seeing the actual code it could be he is misusing signals too, but from your explanation I'd go with the first option.
Signals and slots mechanism is a central feature of Qt.
In general, signals and slots are preferred/used because:
They allow asynchronous execution via queued connections.
They are loosely coupled.
They allow to connect n signals to one slot, one signal to n slots and signal to another signal.
In your project, if signal-slot mechanism has been used to achieve the above, then it is likely the right usage.
GUI input handling isn't the only place where signal-slot mechanism is used.
Unless we know your project's use cases it is difficult to comment if the signal-slot mechanism has been misused/overused.
We are trying to write a portable shared library that makes use of some Qt classes for convenience (mainly QTimer and QTcpSocket); no GUI stuff, though. The according signal/slot connections appear to require some Qt event loop, so we "prime" a QCoreApplication as outlined in this answer. Accordingly, we set up a worker object that does the heavy lifting and move it to a QThread.
The problem we run into now is that the queued connections between the QThread's owner object (within the main thread) and the worker object within the QThread seem to never get handled on Linux systems, at least as long as the program that implements our library does not provide any further Qt event loop of its own in the main thread. This is not very helpful, since the data passed from the worker to the main thread should be passed further using some callback functions, which now never get called, though.
My question is thus: is there a way to get an event loop to work in the library main thread without locking it or the host program up (which seems to be the case when just putting a QCoreApplication::exec() or similar there)? Or will we have to set up a different inter-thread communication scheme (independent from Qt) in order to deal with these data transfers?
Since we do not know if the host software is going to run on a QApplication or not, ideally I'd also have a check for that before setting up a main thread event loop. Is a simple if(qApp != nullptr) enough for that?
P.S.: A few things I tried but which did not work for me, either:
Settings up a QEventLoop in a std::thread launched from the main thread (probably not working because still not in the main thread)
Setting up a QEventLoop in the main thread class and triggering its processEvents() function periodically using a QTimer (probably not working due to the missing event loop for the QTimer::timeout signal in the main function)
Starting the QCoreApplication in a std::thread (gives a run-time warning on Windows that QCoreApplication should be started in the main thread)
In Qt parlance, a callback is called Qt::DirectConnection. But of course those callbacks will run on your worker thread. But that’d be the case with any other library that uses callbacks, so Qt is not a problem here, and neither is your code: the basic idea has this property.
If the host application is not using an event loop (any event loop, not necessarily Qt’s), then there’s nothing you can do other than polling – see below.
If the host application runs an X11 event loop, then you need to ensure that your copy of Qt is using the same underlying event loop as the host application. Usually, this would be the glib’s event loop, and then it should work automagically. Otherwise, you’ll need to pass to the user the file descriptor of the synchronization primitive used by Qt’s event loop, and the user will need to integrate it into their event loop. You’ll face the same problem whether you use Qt or not: rolling your own communication method won’t fix it, since you still need a waitable primitive that will interoperate with whatever event loop the user is using.
The user can of course poll for callbacks whenever they feel like it: expose a mainPoll() method that forwards to QCoreApplication::processEvents().
Despite accepting another answer (which I deem more correct), I'd still like to mention a workaround that worked surprisingly well: We actually managed to get around the event loop/thread problems on most systems by connecting the worker thread signals with lambda functions in constructor of the class that sets up the worker.
Now, I doubt that this behaviour is properly thread-safe, and having relatively lengthy lambda functions declared in connect function calls is certainly not good style. But in case anyone else ends up struggling with this issue, this may be a short-term solution or (temporary) workaround.
When should moveToThread be preferred over subclassing QThread?
This link shows that both methods work. On what basis should I decide what to use from those two?
I would focus on the differences between the two methods. There isn't a general answer that fits all use cases, so it's good to understand exactly what they are to choose the best that fits your case.
Using moveToThread()
moveToThread() is used to control the object's thread affinity, which basically means setting the thread (or better the Qt event loop) from which the object will emit signals and its slots will be executed.
As shown in the documentation you linked, this can be used to run code on a different thread, basically creating a dummy worker, writing the code to run in a public slot (in the example the doWork() slot) and then using moveToThread to move it to a different event loop.
Then, a signal connected to that slot is fired. Since the object that emits the signal (the Controller in the example) lives in a different thread, and the signal is connected to our doWork method with a queued connection, the doWork method will be executed in the worker thread.
The key here is that you are creating a new event loop, run by the worker thread. Hence, once the doWork slot has started, the whole event loop will be busy until it exits, and this means that incoming signals will be queued.
Subclassing QThread()
The other method described in Qt's documentation is subclassing QThread. In this case, one overrides the default implementation of the QThread::run() method, which creates an event loop, to run something else.
There's nothing wrong with this approach itself, although there are several catches.
First of all, it is very easy to write unsafe code, because the run() method is the only one in that class that will be actually run on another thread.
If as an example, you have a member variable that you initialize in the constructor and then use in the run() method, your member is initialized in the thread of the caller and then used in the new thread.
Same story for any public method that could be called either from the caller or inside run().
Also slots would be executed from the caller's thread, (unless you do something really weird as moveToThread(this)) leading to extra confusion.
So, it is possible, but you really are on your own with this approach and you must pay extra attention.
Other approaches
There are of course alternatives to both approaches, depending on what you need. If you just need to run some code in background while your GUI thread is running you may consider using QtConcurrent::run().
However, keep in mind that QtConcurrent will use the global QThreadPool. If the whole pool is busy (meaning there aren't available threads in the pool), your code will not run immediately.
Another alternative, if you are at the least on C++11, is to use a lower level API such as std::thread.
As a starting point: use neither. In most cases, you have a unit of work that you wish to run asynchronously. Use QtConcurrent::run for that.
If you have an object that reacts to events and/or uses timers, it's a QObject that should be non-blocking and go in a thread, perhaps shared with other objects.
Such an object can also wrap blocking APIs.
Subclassing QThread is never necessary in practice. It's like subclassing QFile. QThread is a thread handle. It wraps a system resource. Overloading it is a bit silly.
Simple answer is ALWAYS.
When you move object to thread:
it is easy to write test for code
it is easy to refactor code (you can use thread but you don't have to).
you do not mix functionality of thread with business logic
there is no problem with object lifetime
When you subclass QThread
it is harder to write test
object clean up process can get very confusing leading to strange errors.
There is full description of the problem from Qt blog: You’re doing it wrong….
QtConcurrent::run is also very handy.
Please remember that by default slots are trying to jump between treads when signal is send from other thread object is assigned to. For details see documentation of Qt::ConnectionType.
QThread is low level thread abstraction, first look at high level API QtConcurrent module and QRunnable
If nothing of these is suitable for you, then read this old article, it tells how you should use QThread. Think about thread and task performed in this thread as a separate objects, don't mix them together.
So, if you need to write come custom, specific or extended thread wrapper then you should subclass QThread.
If you have QObject derived class with signals and slots, then use moveToThread on it.
In other cases use QtConcurrent, QRunnable and QThreadPoll.
Can someone explain in simple terms the "signals and slots" pattern?
Signals and slots are a way of decoupling a sender (the signal) and zero or more receivers (the slots). Let's say you a system which has events that you want to make available to any other part of the system interested in those events. Rather than hard-wiring the code that generates event to the code that wants to know about those events, you would use a signals and slots pattern.
When the sender signals an event (usually by calling the function associated with that event/signal) all the receivers for that event are automatically called. This allows you to connect and disconnect receivers as necessary during the lifetime of the program.
Since this question was tagged C++, here is a link to the Boost.Signals library which has a much more thorough explanation.
I think one can describe signals and slots best when you are looking at them as a possible implementation vehicle for the Observer Pattern or Publish/Subscriber Pattern. There is one signal, for example buttonPressed(IdType) on the Publisher Side. Whenever the button is pressed, all slots that are connected to that signal are called. Slots are on the Subscriber Side. A slot could for example be sendMail(IdType) .
Along with the event "button pressed", the slot would know which button was pressed, since the id would have been handed over. IdType represents the type of the data sent over the connection between the Publisher and the Subscriber. An operation possible for the Subscriber would be connect(signal, slot) which could connect buttonPressed(IdType) with sendMail(IdType), so that if the button is pressed, that particular slot is called.
The good thing about this is that the subscriber (the slot side) doesn't need to care about details of the signal. It just needs to connect. Thus, here we have a great deal of loose coupling. You can change the buttons implementation, but the interface for the slots would still be the same.
Look at Qt Signals/Slots or Boost Signals for more informations.
Imagine having a GUI in your application. Most of the time, control flow wouldn't be very linear, i.e. instead of having a clear sequence of actions you'd have a user that interacts with the GUI (like buttons, menus etc.).
This is essentially an event driven model which can be implemented quite nicely with the signals and slots pattern. signals are events which are generated by objects (think GUI components) and slots are the receivers of those events.
Here is an example: imagine you have a checkbox, represented as an object in your programming language. Multiple things can happen to that checkbox: it can be toggled, which in turn also means that it's either set or unset. Those are the signals which it can emit. We will name them checkboxToggled, checkboxSet and checkboxUnset. As you see, in this example, the checkbox will always emit the checkboxToggled signal when toggled, but also exactly one of the two other signals, depending on how the state changes.
Now imagine having some other objects, namely a label, which for the sake of this example always exists as an object but can "appear" and "disappear" and a system beep (also represented by an object), which can simply beep. Those are the slots those objects have. We will call them "messageAppear", "messageDisappear" and "beep".
Suppose you want the system beep to beep everytime the checkbox is toggled, and the label to appear or disappear depending on whether the user checked or cleared the checkbox.
You would thus connect the following signals to the following slots (signals on the left, slots on the right):
checkboxToggled -> beep
checkboxSet -> messageAppear
checkboxUnset -> messageDisappear
That's basically it.
signals and slots may also have arguments. For example, using a slider which sets a numerical value, you would like to send the changed value along with the emitted signal as soon as the user moved the slider: sliderChanged(int).
Of course, to actually do something useful you would write some own classes which would contain some own signals and slots. This is done quite easily and using these own signals and slots, you have a nice way to interact with the GUI or other parts of your code in an event driven manner.
Keep in mind that signals and slots are often symmetric in the sense that there may often be a signal corresponding to a slot. For example, a checkbox may emit a signal when toggled, but it may also contain a slot that toggles the checkbox itself. It would be easy to implement to separate checkboxes that are always set oppositely to each other.
I'm assuming you're talking about QT's signals and slots.
It's very simple.
An instance of a class can fire a signal and another instance of perhaps another class can catch that signal in a slot. It's sort of like a function call only that the guy that calls the function doesn't need to know who wants to receive the call.
The best way to illustrate is with an example.
The class QPushButton has a signal QPushButton::clicked(). That signal is fired whenever the button is clicked. The push button doesn't need to know who's interested to know that a click occurred. it just fires the signal and whoever's interested can connect to it.
The QDialog in which the button is placed in is infact interested to know when the button was clicked. It has the slot MyDialog::buttonClicked(). On MyDialog c'tor you need to connect() the buttons click() signal to the dialog's buttonClicked() slot so that the slot will be called when the signal is fired.
A bunch of more advanced stuff:
Arguments, a signal can have arguments and these arguments can optionally be passed to the slot as well.
cross thread calls - If you're making a signal-slot connection that needs to be cross thread then QT will automatically buffer the signals and queue them to the right thread. This happens automatically for instance when a GUI thread needs to communicate to a working thread.
Here's more information in QT's documentation.
The best example and explanation I've found for signals and slots is this code project article.
There is a common misunderstanding that classes are nouns like Person, Dog, Bicycle and such. Then it makes sense to think that a person (instance) has a dog and a bicycle.
Let's start with what objects are (supposed to be). Objects are data and procedures. What are programs? Data and procedures. Objects are supposed to be (relatively) "small" independent sub-programs. Because oo programming is taught very vaguely and misused (citation needed), people think everything needs to be a class or an object. This is not so, objects are "small" independent programs with a "small" API (public subroutines).
Some programmers don't even break their project into sub-programs and simply use objects where data and procedures are more suitable.
Now, assuming that we agree that objects are programs, we may agree that in most cases, programs don't need to have copies of other programs of a similar size and complexity (i.e an object does not a pointer to another object), it may need smaller programs for managing data (like data-structures) but imho does not need another object.
Why? Because coupling objects makes them dependent. Why is that bad? Because when objects are independent you can test them and also promise other programmers and clients that the object (a small independent program) is capable of performing certain tasks with high certainty. You can also be sure that it continues to perform as long as no changes were made to that object.
So what are slots and signals? If you understand that objects are like programs and they should not ideally hold copies or pointers to other objects than you need some way for them to communicate. For instance, processes that run on your computer can use sockets, IP addresses and ports to communicate. Objects can use something very similar to RPC called signals and slots. These are a data-structure intended as an intermediary between two larger objects that store object's subroutines (slots) and allow other objects to call (signal) these subrutines (slots) with suitable parameters without knowing anything about these other objects other than which parameters they require.
So the underlying structure are sets (possibly arrays) of (possibly) strongly typed procedure pointers, that other objects can call with suitable parameters without a pointer to these objects. The callers only need access to the signal object instead (which holds no implementation details) that defines the expected parameters.
This is also flexible because it allows some special use cases like slots which only respond to the signal once, multiple slots for one signal and other similar use cases like debouncing.