Signals and Slots in Depth

Table of contents:

The signals and slots mechanism is fundamental to Qt programming. It enables the application programmer to bind objects together without the objects knowing anything about each other. We have already connected some signals and slots together, declared our own signals and slots, implemented our own slots, and emitted our own signals. Let's take a moment to look at the mechanism more closely.

Slots are almost identical to ordinary C++ member functions. They can be virtual, they can be overloaded, they can be public, protected, or private, and they can be directly invoked like any other C++ member functions. The difference is that a slot can also be connected to a signal, in which case it is automatically called each time the signal is emitted.

The connect() statement looks like this:

connect (sender, SIGNAL(signal), receiver, SLOT(slot));

where sender and receiver are pointers to QObjects and where signal and slot are function signatures without parameter names. The SIGNAL() and SLOT() macros essentially convert their argument to a string.

In the examples we have seen so far, we have always connected different signals to different slots. There are more possibilities to explore:

  • One signal can be connected to many slots:

    connect(slider, SIGNAL(valueChanged(int)),
     spinBox, SLOT(setValue(int)));
    connect(slider, SIGNAL(valueChanged(int)),
     this, SLOT(updateStatusBarIndicator(int)));

    When the signal is emitted, the slots are called one after the other, in an arbitrary order.

  • Many signals can be connected to the same slot:

    connect(lcd, SIGNAL(overflow()),
     this, SLOT(handleMathError()));
    connect(calculator, SIGNAL(divisionByZero()),
     this, SLOT(handleMathError()));

    When either signal is emitted, the slot is called.

  • A signal can be connected to another signal:

     this, SIGNAL(updateRecord(const QString &)));

    When the first signal is emitted, the second signal is emitted as well. Apart from that, signalsignal connections are indistinguishable from signalslot connections.

  • Connections can be removed:

    disconnect(lcd, SIGNAL(overflow()),
     this, SLOT(handleMathError()));

    This is rarely needed, because Qt automatically removes all connections involving an object when that object is deleted.

When connecting a signal to a slot (or to another signal), they must both have the same parameter types in the same order:

connect(ftp, SIGNAL(rawCommandReply(int, const QString &)),
 this, SLOT(processReply(int, const QString &)));

Exceptionally, if a signal has more parameters than the slot it is connected to, the additional parameters are simply ignored:

 this, SLOT(checkErrorCode(int)));

If the parameter types are incompatible, or if the signal or the slot doesn't exist, Qt will issue a warning at run-time. Similarly, Qt will give a warning if parameter names are included in the signal or slot signatures.

Qt s Meta Object System

One of Qt's major achievements has been the extension of C++ with a mechanism for creating independent software components that can be bound together without any component knowing anything about the other components it is connected to.

The mechanism is called the meta-object system, and it provides two key services: signals and slots, and introspection. The introspection functionality is necessary for implementing signals and slots, and allows application programmers to obtain "meta-information" about QObject subclasses at runtime, including the list of signals and slots supported by the object and its class name. The mechanism also supports properties (for Qt Designer) and text translation (for internationalization).

Standard C++ doesn't provide support for the dynamic meta-information needed by Qt's meta-object system. Qt solves this problem by providing a separate tool, moc, that parses Q_OBJECT class definitions and makes the information available through C++ functions. Since moc implements all its functionality using pure C++, Qt's meta-object system works with any C++ compiler.

The mechanism works as follows:

  • The Q_OBJECT macro declares some introspection functions that must be implemented in every QObject subclass: metaObject(), className(), tr(), and a few more.
  • Qt's moc tool generates implementations for the functions declared by Q_OBJECT and for all the signals.
  • QObject member functions such as connect() and disconnect() use the introspection functions to do their work.

All of this is handled automatically by qmake, moc, and QObject, so you rarely need to think about it. But if you are curious, you can look at the C++ source files generated by moc to see how the implementation works.

So far, we have only used signals and slots with widgets. But the mechanism itself is implemented in QObject, and isn't limited to GUI programming. The mechanism can be used by any QObject subclass:

class Employee : public QObject
 Employee() { mySalary = 0; }

 int salary() const { return mySalary; }

public slots:
 void setSalary(int newSalary);

 void salaryChanged(int newSalary);

 int mySalary;

void Employee::setSalary(int newSalary)
 if (newSalary != mySalary) {
 mySalary = newSalary;
 emit salaryChanged(mySalary);

Notice how the setSalary() slot is implemented. We only emit the salaryChanged() signal if newSalary ! = mySalary. This ensures that cyclic connections don't lead to infinite loops.

Part I: Basic Qt

Getting Started

Creating Dialogs

Creating Main Windows

Implementing Application Functionality

Creating Custom Widgets

Part II: Intermediate Qt

Layout Management

Event Processing

2D and 3D Graphics

Drag and Drop


Container Classes





Providing Online Help


Platform-Specific Features

C++ GUI Programming with Qt 3
C++ GUI Programming with Qt 3
ISBN: 0131240722
EAN: 2147483647
Year: 2006
Pages: 140

Similar book on Amazon

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net