Qt


... [ Seminar Linux und Apache ] ... [ Thema Komponentenmodell von KDE 2 ] ... [ DCOP ] ...

Übersicht: Qt


Einleitung

Qt wird von der norwegischen Firma Trolltech entwickelt.
Es ist kommerzielle Software, die aber von Trolltech für nicht kommerzielle Projekte unter dem Namen Qt Free Edition frei zur Verfügung gestellt wird.
Die Qt Free Edition wird vertrieben unter den Open-Source-License: QPL (Q Public License) und GPL (GNU General Public License).

Qt ist eine in C++ geschriebene Klassen-Bibliothek, die auf der einen Seite eine Menge von sichtbaren (Buttons, Labels) und unsichtbaren (timer) Elementen zur Verfügung stellt. Andererseits ist der Kommunikationsmechanismus (Signals/Slots) der von Qt bereitgestellt wird ein sehr mächtiges Werkzeug. Qt ist die Grundlage von KDE. Es erleichtert durch die zur Verfügung gestellten Klassen / Elemente die GUI-Programmierung ungemein. Die traditionelle X Window Programmierung war eine komplizierte, anstrengende und zeitraubende Aufgabe.
Für ein so großes Projekt wie KDE war es nicht mehr möglich, diesen traditionellen Weg zu gehen. Das KDE-Projekt mußte sich im Laufe seiner Entwicklung für ein Toolkit entscheiden, um der ständig wachsenden Größe des Projektes Rechnung zu tragen. Die Wahl viel auf Qt und nicht auf konkurierende Toolkits wie gtk, xforms, xlib, da es von den Mitgliedern des Projektes für das am besten geeignete Toolkit gehalten wurde.
Qt enthält alle wichtigen Elemente die für eine GUI-Programmierung gebraucht werden, aber auch nicht mehr. Der zu verwaltende Overhead ist also sehr gering. Da Qt in C++ programmiert worden ist, bietet es alle Vorteile der objektorientierten Programmierung. Wiederverwendbarkeit und Effizienz sind hier als erstes anzuführen.
Auch wenn die Qt Free Edition keinen Support durch die Firma Trolltech beinhaltet, werden trotzdem alle Verbesserungen in den kommerziellen Versionen von Qt auch an die Free Edition weitergegeben. Folglich entspricht auch die Free Edition immer dem neuesten Stand der Entwicklung von Qt.

Mit den Worten der KDE-Entwickler gesprochen:
In our opinion there is no better toolkit available for Unix and that it would have been a grave mistake to try to build KDE on anything but the best.

Signal-/Slot-Konzept

Callback-Routinen sind Funktionen oder Methoden, die ausgeführt werden sollen, sobald ein Widget einer Interaktion des Benutzers unterliegt, z.B. wenn ein Button gedrückt wird, ein Menüpunkt ausgewählt oder eine Scrollbar verschoben wird. Callback-Routinen in Qt werden durch das sehr mächtige Signal-/Slot-Konzept realisiert. Dazu sind in den Klassendefinitionen der Qt-Klassen zusätzliche Methoden als signal oder slot deklariert.
Diese Methoden können beliebige Parameteranzahlen und Typen haben, der Rückgabewert muss aber in jedem Fall void sein. Bei Callback-Routinen Konzepten anderer Toolkits besteht diese Möglichkeit nicht, sie lassen meist nur eine sehr einfache Parameterstruktur zu. Dies ist zurückzuführen auf die Tatsache das Callbacks Pointer auf Funktionen sind, die dann bei einem eintretenden Ereignis ausgeführt werden. Diese Funktionspointer sind aber nicht in der Lage, jede Art und Anzahl von Parametern zu verwenden.
Damit eine Klasse Signal- und Slot-Methoden benutzen kann, muss sie von der Klasse QObject abgeleitet sein. (Das sind z.B. alle GUI-Widgets, da sie von QWidget abgeleitet sind, welches seinerseits von QObject abgeleitet ist.)

Die Slot-Methoden sind Methoden, die eine Aktion als Folge einer Interaktion ausführen sollen. Sie müssen vom Programmierer mit Code gefüllt werden. Slot-Methoden werden also bei einem auftretendem Signal abgearbeitet, sie können aber auch wie ganz normale Methoden aufgerufen werden. Eine Routine zur Speicherung einer Datei sollte z.B. als Slot-Methode implementiert werden. Sie würde auf ein Drücken des Menüpunktes Speichern reagieren, ebenso wäre es möglich, diese Routine regelmäßig aufzurufen, um eine Sicherheitsspeicherung zu erzielen.

Signal-Methoden werden vom Programmierer nur deklariert, jedoch nicht mit Code gefüllt. Der Code für die Methode wird vom Meta-Object-Compiler (MOC) generiert und nachher zum Programm hinzugelinkt. Signal-Methoden führen keine Aktionen aus, sondern rufen nur Slot-Methoden auf, mit denen sie verbunden sind.

Beispielimplementation zur Benutzung des Signal-/Slot-Konzept (Code ist nicht vollständig)
	   1 
	   2   MyWindow::MyWindow() : QWidget()
	   3   {
	   4     // Create button1 and connect button1->clicked() to this->slotButton1()
	   5     button1 = new QPushButton("Button1", this);
	   6     connect(button1, SIGNAL(clicked()), this, SLOT(slotButton1()));
	   7   
	   8     // Create button2 and connect button2->clicked() to this->slotButton2()
	   9     button2 = new QPushButton("Button2", this);
	  10     connect(button2, SIGNAL(clicked()), this, SLOT(slotButton2()));
	  11 
	  12     // When any button is clicked, call this->slotButtons()
	  13     connect(button1, SIGNAL(clicked()), this, SLOT(slotButtons()));
	  14     connect(button2, SIGNAL(clicked()), this, SLOT(slotButtons()));
	  15   }
	  16 
	  17   void MyWindow::slotButton1()   // Slot is called when button1 is clicked.
	  18   { cout << "Button1 was clicked" << endl; }
	  19 
	  20   void MyWindow::slotButton2()  // Slot is called when button2 is clicked
	  21   { cout << "Button2 was clicked" << endl; }
	  22 
	  23   void MyWindow::slotButtons() // Slot is called when 1 or 2 were clicked
	  24   { cout << "A button was clicked" << endl; }
	  25 
	

Nachdem der Knopf button1 erzeugt wurde (Zeile5), wird er mit Hilfe des connect Befehls (Z.6) an eine Slot-Methode gebunden. In diesem Fall handelt es sich um die Methode slotButton1 (Z.17).
button2 (Z.9) wird an die Methode slotButton2 (Z.20) gebunden (Z.6).
Beim Klicken auf einer der Buttons würde dann die entsprechende Slot-Methode ausgeführt werden.

Das Signal-/Slot-Konzept von Qt läßt aber auch die Verknüpfung von mehreren Signalen an eine Slot-Methode zu. Die Zeilen 13 und 14 verbinden (connect) beide Buttons mit der selben Slot-Methode slotButtons, es wäre hiermit egal, auf welchen der Button geklickt wird, die Methode würde ausgeführt werden.
Ebenso ist es möglich mit einem Signal mehrere Slot-Methoden auszuführen.

Das Verbinden von Signalen ist kein statischer Prozess, es ist möglich dynamisch zur Laufzeit des Programms Verbindungen zu erstellen oder diese mit Hilfe der Methode disconnect auch wieder zu lösen.
Qt übernimmt das Lösen von Verbindungen automatisch im Destruktor von QObject, so dass ein Programmabsturz aufgrund eines Aufrufs einer nicht mehr vorhandenen Slot-Methode ausgeschlossen ist.

MOC (Meta-Object-Compiler)

Der Meta-Object-Compiler ist ein nützliches Tool im Qt Paket. Es handelt sich um keinen wirklichen Compiler (obwohl der Name es vermuten lassen würde), MOC konvertiert stattdessen Qt Klassen Definitionen in C++ Code.
MOC sucht dafür im Quellcode der Klassen nach Qt-Schlüsselwörtern und ersetzt diese durch deutlich längeren und komplizierten Quellcode.
Die MOC Schlüsselwörter sind: Q_OBJECT, public slots:, protected slots:, private slots:, und signals:.
Für den Applikationsentwickler bedeutet dies eine riesige Zeit- und Aufwandsersparnis, da er sich nicht um die interne Verarbeitung des Signal-/Slot-Konzepts kümmern muß.
Dieses Beispiel zeigt die Komplexität der Ersetzungen.

Headerdatei mit Qt-Schlüsselwörtern
	   1 
	   2   #include <qwidget.h>
	   3   #include <qpushbutton.h>
	   4   
	   5   class MyWindow : public QWidget
	   6   {
	   7     Q_OBJECT    // Enable signals and slots
	   8   public:
	   9     MyWindow();
	  10   public slots:   // This slots section is public
	  11     void slotButton(); // A public slot
	  12   private:
	  13     QPushButton *button;
	  14   };
	  15 
  


Programmcompilation:
	   1 
	   2  g++ -I$QTDIR/include -c main.cpp
	   3  moc mywindow.h -o mywindow.moc
	   4  g++ -I/$QTDIR/include -c mywindow.cpp
	   5  g++ -o myprog main.o mywindow.o -L/$QTDIR/lib -lqt
	   6 
	

Nachdem die Datei: main.cpp (Zeile2) compiliert wurde, werden mit Hilfe des Meta-Object-Compilers sämtliche Qt-Schlüsselwörter durch C++ Code ersetzt(Z.3). Jetzt erst ist es möglich die Datei: mywindew.cpp (Z.4) zu übersetzen,da ihr Headerfile: mywindow.moc kein Qt-Code mehr enthält.
Abschließend werden die Dateien noch zu dem ausführbarem Programm: myprog zusammengelinkt (Z.5).

... [ Seminar Linux und Apache] ... [ Thema Komponentenmodell von KDE 2 ] ... [ nach oben ] ... [ DCOP ] ...