Login
Login-Name Passwort


 
Newsletter
Werbung

Mo, 19. Juli 1999, 00:00

KDE-Programmierung: Signals und Slots

Was sind Signals und Slots?

Das Eventhandling ist in vielen Toolkits und unter den meisten Betriebssystemen eine komplizierte und fehlerträchtige Angelegenheit. Nicht so unter Qt. Die Programmierer von Qt haben ihr Toolkit mit einem einfachen und leicht verständlichen Mechanismus zum Eventhandling ausgestattet.

Nehmen wir z.B. einen simplen Button. So bald der User ihn anklickt, sendet er das Signal clicked() aus. Dieses Signal wiederum ist mit einem Slot namens doSomething() verbunden. Da ein Slot eine fast gewöhnliche Funktion ist, würde bei jedem Anklicken des Buttons z.B. eine AboutBox gezeigt werden, eine Datei geöffnet oder gespeichert werden oder irgend eine andere Reaktion auf das Anklicken des Buttons erfolgen.

Signals und Slots in Aktion

Um nun zu herauszufinden, wie man so etwas programmiert, nehmen wir eine erweiterte Version von Word2HTML etwas genauer unter die Lupe.

/* toplevel.h */
#ifndef _TOPLEVEL_H_
#define _TOPLEVEL_H_
#include <kapp.h>
#include <ktmainwindow.h>
#include <kmenubar.h>
#include <qpopupmenu.h>
#include <qmessagebox.h>
class TopLevel : public KTMainWindow
{
 Q_OBJECT
public:
 TopLevel();
 void closeEvent(QCloseEvent *);
private slots:
 void aboutApp();
};
#endif

Erklärung

private slots:
 void aboutApp();

Hier wird ein neuer Slot für die Klasse TopLevel deklariert. Er wird später eine AboutBox öffnen.

/* toplevel.cpp */
#include "toplevel.h"
TopLevel::TopLevel()
{
 QPopupMenu *file = new QPopupMenu;
 file->insertItem(i18n("&Quit"), kapp, SLOT(quit()));
 QPopupMenu *help = new QPopupMenu;
 help->insertItem(i18n("&About"), this, SLOT(aboutApp()));
 KMenuBar *menu = new KMenuBar(this);
 menu->insertItem(i18n("&File"), file);
 menu->insertSeparator();
 menu->insertItem(i18n("&Help"), help);
 setMenu(menu);
 resize(500,400);
 setCaption("Word2HTML");
}
void TopLevel::closeEvent(QCloseEvent *)
{
 kapp->quit();
}
void TopLevel::aboutApp()
{
 QMessageBox::about(this, "About Word2HTML","Hello World");
}

Erklärung

 QPopupMenu *file = new QPopupMenu;

Das Datei-Menü wird erzeugt. Es wird später als Eintrag im Menü des Hauptfensters erscheinen.

 file->insertItem(i18n("&Quit"), kapp, SLOT(quit()));

Der Eintrag "Quit" wird in des Menü eingefügt. Gleichzeitig wird er mit dem Slot quit(), des kapp-Objekts verknüpft, so dass beim Anklicken von Quit das Programm beendet wird. Das Makro i18n wird für die Internationalisierung der Anwendung benötigt. Setzen Sie einfach alle für den Anwender sichtbaren Strings in dieses Makro und achten Sie darauf, dass "kapp.h" eingebunden wurde. In einer weiteren Ausgabe dieses Workshops werde ich genauer auf die Internationalisierung eingehen.

 QPopupMenu *help = new QPopupMenu;
 help->insertItem(i18n("&About"), this, SLOT(aboutApp()));

Im Prinzip das selbe wie oben. Nur wird hier das Hilfe-Menü erzeugt und der Eintrag About mit dem selbstdefinierten SLOT aboutApp() verknüpft.

 KMenuBar *menu = new KMenuBar(this);
 menu->insertItem(i18n("&File"), file);
 menu->insertSeparator();
 menu->insertItem(i18n("&Help"), help);

Das Menü für unser Fenster wird erzeugt und durch den this-Zeiger wird ihm mitgeteilt, dass es zur Klasse TopLevel gehört (bei allen grafischen Steuerelementen sehr wichtig). Danach werden ihm die beiden Popup-Menüs als Einträge zugewiesen. Die vorletzte Zeile bewirkt, dass das Hilfemenü auf der rechten Seite des Fensters plaziert wird (nur mit Motif-Look-and-Feel).

 setMenu(menu);

Das Hauptfenster wird angewiesen, sich um die Verwaltung des Menüs zu kümmern. Sonst würde die Größe des Menüs nicht automatisch an das Hauptfenster angepasst werden.

void TopLevel::aboutApp()
{
 QMessageBox::about(this, "About Word2HTML","Hello World");
}

Der Slot aboutApp() wird definiert. Er ist, wie jeder andere Slot, eine ganz gewöhliche Funktion, die in der Header-Datei eben mit dem Schlüsselwort Slot deklariert wurde. Die Funktion about der Klasse QMessageBox macht nichts anderes als eine AboutBox mit dem Titel »About Word2HTML« und der Meldung »Hello World« zu zeigen.

Am besten überschreiben Sie ihre alte TopLevel-Klasse mit den neuen Quellen und kompilieren das Programm einfach neu.

Noch ein wenig Theorie

Das obige Beispiel ist eigentlich ganz einfach. Man muss aber bedenken, dass die Klasse QPopupMenu ein Einzelfall ist. Bei allen anderen Klassen werden Signals und Slots nicht schon von Anfang an miteinander verknüpft. Wie das folgende Beispiel zeigt, ist aber auch das nicht viel schwerer.

 QPushButton *button = new QPushButton(this);
 button->setGeometry(10,10,80,25);
 button->setText("Button");

Es wird ein Button von Qt erstellt. Seine Position und seine Größe werden definiert. Er bekommt den Text »Button«. Der wirklich interessante Teil kommt aber erst jetzt:

 connect(button, SIGNAL(clicked()), this, SLOT(buttonClicked()));

Der erste Parameter ist ein Zeiger auf die Klasse, der das Signal gehört, das verknüpft werden soll. Der zweite das Makro SIGNAL, das als Parameter das entsprechende Signal erhält. Als dritter Parameter wird die Klasse, deren Slot verknüpft werden soll, angegeben, und als vierter und letzter das Makro SLOT mit dem entsprechenden Slot der Klasse.

Wenn Sie damit noch irgendwelche Probleme haben, dann bauen Sie den Button doch einfach mal in unser bisheriges Programm ein. Sie müssen lediglich den Header "qpushbutton.h" in "toplevel.h" einbinden und die beiden Quellcodefragmente in den Konstruktor von TopLevel aufnehmen. Jetzt ändern Sie den Slot von buttonClicked() auf aboutApp() und schon wird bei jedem Anklicken des Buttons die AboutBox gezeigt.

Kommentare (Insgesamt: 0 || Kommentieren )
Pro-Linux
Pro-Linux @Facebook
Neue Nachrichten
Werbung