Revision: Signals and Slots

The following sources have been used in making this material:

If your knowledge on signals and slots is rusty or they are a completely new concept to you, you can get started with the Programming 2 material on Qt basics.

Signals and slots

In Qt, signals and slots are a way for objects to communicate with eachother. A signal is emitted when some event occurs in the program. For example, when a button on the UI is pushed, the button (a QPushButton widget) notifys the other widgets and objects about this by emitting a signal (emit clicked()). A slot is a function called as a response to an emitted signal. For example, a slot findClicked() is executed as a response to a button click.

All subclasses of QObject or one of its subclasses can contain signals and slots. In practice, two things are required for the signal and slot mechanism to work. All classes that contain signals or slots must:

  • mention the Q_OBJECT macro at the top of their declaration.
  • be derived from QObject

Objects emit signals when their state changes in a way that may be interesting to other objects. The objects do not need to know anything about eachother. In fact, the only thing the object does is emit the signal. It does not know, care or need to know, if anyone receives the signals emitted and vice versa, a slot does not know if any signals are connected to it. Qt's signal and slot mechanism makes sure that if the signal is connected to a slot, the slot is automatically called with the signal's parameters.

One signal can be connected to as many slots as needed. If more than one slot is connected, they are called when the signal is emitted one after another in the same order they were connected. Similarly, more than one signal can be connected to the same slot. The slot is called when any of the signals are emitted. A signal can even be connected to another signal to emit the second signal as the first is emitted.

Signals

Qt's widgets have predefined signals. New signals can be defined in the class's signals section of the interface.

signals:
   void amount(const int count, const ObjectType type);

Signals must not be implemented. The meta-object compiler moc generates them automatically. A signal can never have a return type and is always void.

Slots

Slots are C++ functions that can be called normally as any other function. They can also be virtual if needed. In addition, signals can be connected to them. New slots are defined in the class's slots section of the interface.

public slots:
   void setvalue( int value );
   bool doAction();

The programmer implements the slots (slots are C++ functions). Similarly to functions, slots can be either public or private.

Connecting

Signals and slots are connected with QObject::connect(). The preferred syntax is functor based i.e.

connect( sender, &Sender::changeSignal,
         receiver, &Receiver::updateSlot);

where sender is a pointer to the QObject object emitting the signal and receiver is a pointer to the QObject object containing the slot. The second and fourth parameters are the signal and the slot respectively. The biggest benefits with this syntax is the compile-time type checking and the possibility to use lambdas as a part of the connect.

The other way to connect a signal to a slot is to use the SIGNAL and SLOT macros. This is typically referred as the old syntax.

connect( sender, SIGNAL( changeSignal(int)),
         receiver, SLOT( updateSlot(int)));

where the SIGNAL and SLOT macros convert their parameters to strings. Type checking is left as a run time operation. However, you can connect C++ functions to QML function with this syntax.

Meta-object System

The Qt's meta-object system in Qt enables among other things signals and slots. It is based on three things:

# The QObject class as the a base class for objects that can take advantage of the meta-object system. # The Q_OBJECT macro at the beginning of the class declaration is used to enable meta-object features. # The Meta-Object Compiler (moc) supplies each of the QObject subclasses with the necessary code to implement meta-object features. The moc tool reads a C++ source file. For the classes that contain the Q_OBJECT macro, it produces another C++ source file containing the meta-object code for each class. This generated source file is then typically compiled and linked with the class's implementation.

It is possible to use QObject as a base class without the Q_OBJECT macro. This means that signals, slots and the other meta-object features will not be available. For the meta-object system, a QObject subclass without meta code is equivalent to its closest ancestor with meta-object code. Therefore, all subclasses of QObject should use the Q_OBJECT macro even if they do not use signals, slots, and other meta-object system properties.

Posting submission...