0

I was going through a Qt tutorial here, when I came across this following piece of code:

 #include <QObject>

 class Counter : public QObject
 {
     Q_OBJECT

 public:
     Counter() { m_value = 0; }

     int value() const { return m_value; }

 public slots:
     void setValue(int value);

 signals:
     void valueChanged(int newValue);

 private:
     int m_value;
 };

Can anyone explain to me what is the usage of the public slots, signals within the declaration? I though there are only two, public and private. What are they called, and what is their usage?

SexyBeast
  • 7,913
  • 28
  • 108
  • 196
  • 1
    @Cupidvogel: huh, I've missed a link. So, you'd better to read that doc once more... it is Qt basics that you ought to clearly understand. And the official documentation is pretty clear about it. – zaufi Nov 06 '14 at 22:41
  • Looks like it. Better close the question, will you, Barry? – SexyBeast Nov 06 '14 at 22:41
  • It needs 3 more close votes for that. – JBL Nov 06 '14 at 22:42
  • @Cupidvogel In addition to the document, [**this article**](http://woboq.com/blog/how-qt-signals-slots-work.html) depicts the Signal & Slot mechanism under the hood in detail, worth reading. – Tay2510 Nov 07 '14 at 02:11

1 Answers1

3

Signals and slots is a language construct introduced in Qt for communication between objects[1] which makes it easy to implement the Observer pattern while avoiding boilerplate code. The concept is that GUI widgets can send signals containing event information which can be received by other controls using special functions known as slots.

The signal/slot system fits well with the way Graphical User Interfaces are designed. Similarly, the signal/slot system can be used for other non-GUI usages, for example asynchronous I/O (including sockets, pipes, serial devices, etc.) event notification or to associate timeout events with appropriate object instances and methods or functions. It is easy to use and no registration/deregistration/invocation code need to be written, because Qt's Meta Object Compiler (MOC) automatically generates the needed infrastructure.

A commonly used metaphor is a spreadsheet. A spreadsheet has cells that observe the source cell(s). When the source cell is changed, the dependent cells are updated from the event.

Not bad explained from Wikipedia


Since Qt basically invented the concept it would be best for you to actually read the article you posted in your question.

Especially:

Signals

Signals are emitted by an object when its internal state has changed in some way that might be interesting to the object's client or owner. Only the class that defines a signal and its subclasses can emit the signal.

When a signal is emitted, the slots connected to it are usually executed immediately, just like a normal function call. When this happens, the signals and slots mechanism is totally independent of any GUI event loop. Execution of the code following the emit statement will occur once all slots have returned. The situation is slightly different when using queued connections; in such a case, the code following the emit keyword will continue immediately, and the slots will be executed later.

If several slots are connected to one signal, the slots will be executed one after the other, in the order they have been connected, when the signal is emitted.

Signals are automatically generated by the moc and must not be implemented in the .cpp file. They can never have return types (i.e. use void).

A note about arguments: Our experience shows that signals and slots are more reusable if they do not use special types. If QScrollBar::valueChanged() were to use a special type such as the hypothetical QScrollBar::Range, it could only be connected to slots designed specifically for QScrollBar. Connecting different input widgets together would be impossible.

and

Slots

A slot is called when a signal connected to it is emitted. Slots are normal C++ functions and can be called normally; their only special feature is that signals can be connected to them.

Since slots are normal member functions, they follow the normal C++ rules when called directly. However, as slots, they can be invoked by any component, regardless of its access level, via a signal-slot connection. This means that a signal emitted from an instance of an arbitrary class can cause a private slot to be invoked in an instance of an unrelated class.

You can also define slots to be virtual, which we have found quite useful in practice.

Compared to callbacks, signals and slots are slightly slower because of the increased flexibility they provide, although the difference for real applications is insignificant. In general, emitting a signal that is connected to some slots, is approximately ten times slower than calling the receivers directly, with non-virtual function calls. This is the overhead required to locate the connection object, to safely iterate over all connections (i.e. checking that subsequent receivers have not been destroyed during the emission), and to marshall any parameters in a generic fashion. While ten non-virtual function calls may sound like a lot, it's much less overhead than any new or delete operation, for example. As soon as you perform a string, vector or list operation that behind the scene requires new or delete, the signals and slots overhead is only responsible for a very small proportion of the complete function call costs.

The same is true whenever you do a system call in a slot; or indirectly call more than ten functions. On an i586-500, you can emit around 2,000,000 signals per second connected to one receiver, or around 1,200,000 per second connected to two receivers. The simplicity and flexibility of the signals and slots mechanism is well worth the overhead, which your users won't even notice.

Note that other libraries that define variables called signals or slots may cause compiler warnings and errors when compiled alongside a Qt-based application. To solve this problem, #undef the offending preprocessor symbol.

deW1
  • 5,562
  • 10
  • 38
  • 54