Grafische Einheiten (Widgets)

Im Zusammenhang mit der Programmierung von grafischen Oberflächen fällt sehr oft das Wort „Widget“. Doch was ist überhaupt ein Widget? Ein Widget ist eine allgemeine Bezeichnung für eine grafische Einheit. Buttons, Eingabefelder, Listen, Scrollbalken, Menüs, Icons, usw. - das alles sind Widgets. Man kann Widgets gruppieren, es kann z.B. auch ein ganzer Dialog oder ein Fenster als Widget angesehen werden. Durch dieses Prinzip kann die komplette Oberfläche eines Programms in Widgets eingeteilt werden.

Widgets in Qt

In Qt haben alle Widgets eines gemeinsam: Sie sind von der Klasse QWidget abgeleitet. Diese Basisklasse bietet alle notwendigen Methoden um ein Widget zu verwenden. Methoden zum Anzeigen, Ändern der Größe, Behandlung von Events und Kapselung von anderen Widgets sind bereits implementiert. Wird ein Widget nicht in ein anderes eingebettet, so ist es ein Fenster.
Natürlich müssen nicht alle Widgets selbst implementiert werden. Qt bietet bereits eine Vielzahl von fertigen Klassen, die verschiedenste Widgets darstellen. Im Laufe des Tutorials werden immer wieder Widgets verwendet werden, die zuvor nicht explizit erklärt wurden. Diese müssen gegebenenfalls in der Referenz nachgeschlagen werden, in vielen Fällen werden sie aber selbsterklärend sein.
Hier ein paar Beispiele für Widgets, die in Qt bereits vollständig implementiert sind:

Beispielprogramm

Jetzt haben wir einige Widgets gesehen, doch wie verwenden wir sie in unseren Programmen? Nehmen wir folgenden Code und gehen ihn Schritt für Schritt durch:

#include <QApplication>
#include <QWidget>
 
int main( int argc, char *argv[] )
{
  QApplication app( argc, argv );
  QWidget w;
 
  w.resize( 200, 200 );
  w.setWindowTitle( "Widget-Demo" );
  w.show();
 
  return app.exec();
}

Wenn wir das Programm ausführen, erhalten wir folgende Oberfläche:

Widget

Das Programm beendet sich automatisch, nachdem das Fenster geschlossen wurde.

Wie bereits im Kapitel zur Kompilierung des ersten Programms angemerkt, benötigt jedes grafische Programm eine Instanz vom Typ QApplication, die vor jedem Widget erstellt werden muss 1). Dieses Objekt bekommt die Kommandozeilenparameter argc und argv übergeben und startet über die Methode exec() die Event-Schleife. Diese Schleife verwaltet Events wie Benutzereingaben und gibt diese an die betroffenen Widgets weiter. Wird diese Schleife blockiert, können keine Events mehr behandelt werden und die Oberfläche friert ein. Für diese Klasse brauchen wir auch das erste Include. Wie im gesamten Qt-Framework üblich, befinden sich Klassen in einer gleichnamigen Header-Datei, die eingebunden werden muss:

#include <QApplication>

In diesem Programm erstellen wir ein primitives QWidget, ohne echte Funktionalität. Trotzdem muss dafür die entsprechende Datei eingebunden werden:

#include <QWidget>

Nun können wir in unserem Programm beliebig viele Instanzen von QWidget erstellen. Wir erstellen über den Default-Konstruktor einfach ein leeres Widget:

QWidget w;

Wichtig ist, dass zuvor die QApplication-Instanz erstellt wurde!
Die Änderung der Größe des Widgets widerspricht etwas den Qt-Standards und heißt nicht setSize(), sondern resize(). Als Parameter werden die neue Breite und Höhe des Widgets in Pixel übergeben.

w.resize( 200, 200 );

Über setWindowTitle() kann ein Text festgelegt werden, der in der Titelleiste angezeigt wird. Dieser wird nur angezeigt, wenn das Widget ein Fenster ist (d.h. es sich in keinem anderen Widget befindet).

w.setWindowTitle( "Widget-Demo" );

Schlussendlich zeigen wir das Widget noch auf dem Bildschirm über die Methode show() an (setVisible( true ) wäre ebenfalls möglich).

w.show();

Nachdem nun alles für die Ausführung vorbereitet ist, kann die Event-Schleife gestartet werden. Wir verwenden - wie is in Qt-Programmen sehr üblich ist - den Rückgabewert der Schleife gleich als Rückgabewert von unserem Programm.

return app.exec();

Standardmäßig beendet Qt das laufende Programm, wenn das letzte Fenster geschlossen wird. Dieses Verhalten kann über die Methode setQuitOnLastWindowClosed() von unserem QApplication-Objekt verändert werden. Das ist z.B. nützlich, um ein Programm im Systemtray weiterlaufen zu lassen, wenn das letzte Fenster geschlossen wurde.

Abschließendes

Nun haben wir unsere ersten Erfahrungen mit Widgets in Qt gemacht. In den nächsten Kapiteln wird behandelt, wie man auf Ereignisse reagiert und Widgets ineinander verschachtelt.

1)
Ansonsten wird man mit der Fehlermeldung QWidget: Must construct a QApplication before a QWidget zur Laufzeit deutlich darauf hingewiesen