Qt für C++ Anfänger: Signale und Slots

Signale und Slots sind ein Mechanismus von Qt, wie sich verschiedene GUI-Elemente oder Aktionen unterhalten können. Jemand sendet ein Signal aus und ein anderer empfängt dieses. Ein Signal kann z.B. beim Drücken eines Buttons ausgesendet werden. Ein oder mehrere Empfänger, die so genannten Slots, empfangen das Signal und rufen daraufhin eine entsprechende Funktion auf, die z.B. irgendeine Berechnung startet. Als erstes müssen wir uns überlegen, wie man Signale und Slots miteinander verbindet.

Diese Verbindung wird über das connect-Statement hergestellt. connect ist dabei ein Qt-spezifisches Makro, welches vom Präprozessor in echtes C++ umgesetzt wird. Die Syntax sieht wie folgt aus:

connect(Calculate, SIGNAL(clicked()), this, SLOT(addAB()));

"Calculate" ist das Qt-Objekt, das ein Signal aussendet. Calculate ist der Name des QPushButton, den wir im Qt Designer festgelegt hatten.

"SIGNAL(clicked())" bezeichnet das Signal, welches abgefangen werden soll. Objekte können unterschiedliche Signale aussenden. In der Qt-Dokumentation können die für das jeweilige Qt-Objekt verfügbaren Signale nachgeschlagen werden.

"this" bezeichnet die Instanz der Klasse, deren aufzurufende Methode im Folgenden angegeben wird.

"SLOT(addAB())" bezeichnet die Funktion, die aufgerufen werden soll. Für diese Funktion muss natürlich, wie für jede andere C++ Funktion auch, eine Deklaration erstellt werden.

Dieser connect-Befehl muss im Konstruktor unserer Klasse stehen, damit er gleich am Anfang ausgeführt wird. Die Deklaration des Slots addAB() findet im Headerfile statt. Das Headerfile sieht damit folgendermaßen aus:

//--- Taschenrechner.h - start ---

#ifndef TASCHENRECHNER_H
#define TASCHENRECHNER_H

#include "ui_Taschenrechner.h"

class Taschenrechner : public QMainWindow, public Ui::MainWindow {

Q_OBJECT

public:
    Taschenrechner(QMainWindow *parent = 0);
    ~Taschenrechner();
private slots:
    void addAB();
};

#endif //TASCHENRECHNER_H

//--- Taschenrechner.h - end ---

Wie man sieht, findet die Deklaration der Funktion addAB() innerhalb der Klasse statt. Es handelt sich also um eine Memberfunktion. Es wird noch angegeben, dass es sich um eine private Funktion handelt. Mit dem Makro "slots" wird gesagt, dass es sich bei dieser Funktion um einen Slot handelt. Die Datei Taschenrechner.cpp mit der eigentlichen Implementation sieht dann so aus:

//--- Taschenrechner.cpp - start ---

#include "Taschenrechner.h"

Taschenrechner::Taschenrechner(QMainWindow *parent) : QMainWindow(parent) {	
    setupUi(this);
    InputA -> setText("0");
    InputB -> setText("0");

    connect(Calculate, SIGNAL(clicked()), this, SLOT(addAB()));
}

Taschenrechner::~Taschenrechner() { }

void Taschenrechner::addAB() {
    //Hier wird im nächsten Kapitel die Funktion implementiert
}

//--- Taschenrechner.cpp - end ---

Alle Slots und Funktionen, die benötigt werden, werden also einfach in der Datei Taschenrechner.cpp nacheinander aufgelistet. Mit der Angabe "Taschenrechner::" wird mitgeteilt, dass es sich um eine Funktion der Klasse Taschenrechner handelt. Der Funktionskopf muss ansonsten genau so aussehen wie im zugehörigen Headerfile.

Wenn man das Programm nun übersetzt und ausführt, wird man erst einmal keine Veränderung feststellen, da die Funktion addAB() noch leer ist. Als letztes sei angemerkt, dass die Funktion addAB() keinen Wert zurück gibt (void). Ein "return;" schadet zwar nicht, man kann sich die Tipparbeit aber sparen. Nur, wenn es mehrere Ausstiege aus der Funktion gibt, was zum Beispiel bei Schleifen der Fall sein kann, muss ein return verwendet werden.

Siehe auch Bearbeiten