Kapitel 5. Womit beginnen Steuerelemente?

Wer kann sagen, wo das eine endet und das andere beginnt?
— Sun Tzu

Praktisch jede Anwendung verfügt über eine grafische Benutzeroberfläche (GUI, Graphical User Interface). Widgets sind das „Baumaterial” für deren Erstellung. Ein Widget ist nicht nur ein auf dem Bildschirm angezeigter Bereich, sondern eine Komponente, die verschiedene Aktionen ausführen kann – zum Beispiel auf eingehende Signale und Ereignisse reagieren oder Signale an andere Widgets senden. Qt stellt ein vollständiges Arsenal an Widgets bereit: von Menüschaltflächen bis hin zu Dialogfenstern, die für die Erstellung professioneller Anwendungen erforderlich sind. Falls diese Widgets nicht ausreichen sollten, können Sie eigene erstellen, indem Sie Klassen von bereits vorhandenen ableiten.

Die Hierarchie der Widget-Klassen ist in Abb. 5.1 dargestellt. Im zweiten Teil des Buches werden die meisten davon beschrieben. Klassen, die in diesem Teil nicht beschrieben sind, finden Sie in anderen Kapiteln des Buches: QMenu (siehe Kapitel 31), QGLWidget (siehe Kapitel 23), QMainWindow (siehe Kapitel 34), QGraphicsView (siehe Kapitel 21).

Klasse QWidget

Die Klasse QWidget ist grundlegend für alle Widget-Klassen. Ihre Schnittstelle enthält zahlreiche Methoden, Eigenschaften und Definitionen, die jedes Widget benötigt – beispielsweise zum Ändern von Größe, Position, Ereignisverarbeitung usw. Die Klasse QWidget selbst ist, wie aus Abb. 5.1 ersichtlich, von der Klasse QObject abgeleitet und kann daher den Signal-/Slot-Mechanismus und den Mechanismus der Objekthierarchie nutzen. Dadurch können Widgets Nachkommen haben, die innerhalb des Vorgängers angezeigt werden. Dies ist sehr wichtig, da jedes Widget als Container für andere Widgets dienen kann – das heißt, in Qt gibt es keine Trennung zwischen Steuerelementen und Containern. Widgets in Containern können als Container für andere Widgets fungieren, und so weiter bis ins Unendliche. Zum Beispiel enthält ein Dialogfenster die Schaltflächen Ok und Abbrechen – folglich ist es ein Container. Dies ist auch deshalb praktisch, weil Nachkommen-Widgets automatisch den Zustand des Vorgänger-Widgets annehmen, wenn dieser nicht verfügbar oder unsichtbar wird.

Qt6 Widget-Klassenhierarchie – Übersicht der QWidget-Ableitungen
Abb. 5.1. Hierarchie der Widget-Klassen
Wichtig!

In Qt wird zwischen zwei Arten von Hierarchien unterschieden: Klassenhierarchie (Vererbung) und Objekthierarchie (Eltern-Kind-Beziehungen zwischen Objekten). Wenn wir sagen, dass „Widgets Nachkommen haben können”, meinen wir die Objekthierarchie, nicht die Klassenvererbung. Zum Beispiel ist eine Schaltfläche (QPushButton) ein Nachkomme eines Fensters nicht im Sinne der Klassenvererbung (sie wird von QAbstractButton abgeleitet), sondern im Sinne der Objektstruktur – sie ist innerhalb des Fensters platziert und gehört zu ihm.

Widgets ohne Vorgänger werden Widgets der obersten Ebene (Top-level Widgets) genannt und haben ihr eigenes Fenster. Ausnahmslos alle Widgets können Widgets der obersten Ebene sein. Die Position von Nachkommen-Widgets innerhalb des Vorgänger-Widgets kann manuell mit der Methode setGeometry() oder automatisch mithilfe spezieller Layout-Klassen (siehe Kapitel 6) geändert werden. Zum Anzeigen eines Widgets auf dem Bildschirm wird die Methode show() aufgerufen, zum Verbergen die Methode hide().

Nach dem Erstellen eines Widgets der obersten Ebene muss die Methode show() aufgerufen werden

Vergessen Sie nicht, dass nach dem Erstellen eines Widgets der obersten Ebene die Methode show() aufgerufen werden muss, um es auf dem Bildschirm anzuzeigen, andernfalls bleiben sowohl das Fenster als auch die Nachkommen-Widgets unsichtbar.

Die Klasse QWidget und die meisten von ihr abgeleiteten Klassen haben einen Konstruktor mit zwei Parametern:

QWidget(QWidget* pwgtParent = nullptr, Qt::WindowFlags f = Qt::WindowFlags())

Aus der Definition ist ersichtlich, dass Parameter nicht zwingend an den Konstruktor übergeben werden müssen, da sie Standardwerte haben. Das bedeutet, dass ein ohne Argumente aufgerufener Konstruktor ein Widget der obersten Ebene erstellt. Der zweite Parameter Qt::WindowFlags dient zur Festlegung von Fenstereigenschaften und ermöglicht die Steuerung des Erscheinungsbilds und des Anzeigemodus des Fensters (damit das Fenster nicht von anderen Fenstern verdeckt wird usw.). Um das Erscheinungsbild des Fensters zu ändern, müssen im zweiten Parameter des Konstruktors Modifikatorwerte, die mit dem Fenstertyp (Abb. 5.2) durch die bitweise ODER-Operation kombiniert werden (Symbol |), übergeben werden. Ein ähnliches Ergebnis kann durch Aufruf der Methode setWindowFlags() erzielt werden. Zum Beispiel:

wgt.setWindowFlags(Qt::Window | Qt::WindowTitleHint |
                   Qt::WindowStaysOnTopHint);

Abb. 5.2 zeigt einige der Varianten zur Anwendung dieser Werte.

Verschiedene Fenstertypen von Qt-Top-Level-Widgets mit Qt::WindowFlags
Abb. 5.2. Erscheinungsbild der Fenster von Widgets der obersten Ebene
Lassen Sie das Fenster immer im Vordergrund bleiben!

Der Wert Qt::WindowStaysOnTopHint ändert nicht das Erscheinungsbild des Fensters, sondern empfiehlt lediglich, dass das Fenster immer im Vordergrund bleibt und nicht von anderen Fenstern verdeckt wird.

Mithilfe der Slot-Methode setWindowTitle() wird der Fenstertitel festgelegt. Dies ist jedoch nur für Widgets der obersten Ebene sinnvoll. Zum Beispiel:

wgt.setWindowTitle("My Window");

Der Slot setEnabled() versetzt das Widget in einen verfügbaren (enabled) oder nicht verfügbaren (disabled) Zustand. Der Parameter true entspricht dem verfügbaren, false dem nicht verfügbaren Zustand. Um herauszufinden, in welchem Zustand sich das Widget befindet, rufen Sie die Methode isEnabled() auf.

Beim Erstellen eigener Widget-Klassen ist es wichtig, dass das Widget in der Lage ist, Ereignisse zu verarbeiten (siehe Kapitel 14). Zum Beispiel müssen zur Verarbeitung von Mausereignissen mindestens eine der folgenden Methoden überschrieben werden: mousePressEvent(), mouseMoveEvent(), mouseReleaseEvent() oder mouseDoubleClickEvent().

Größe und Koordinaten des Widgets

Ein Widget stellt einen rechteckigen Bereich dar (Abb. 5.3). Es gibt eine ganze Reihe von Methoden, mit denen Sie den Standort und die Abmessungen des Widgets ermitteln können. Die Methoden size(), height() und width() geben die Abmessungen des Widgets zurück. Während die Aufrufe height() und width() Höhen- und Breitenwerte des ganzzahligen Typs zurückgeben, gibt der Aufruf der Methode size() ein Objekt der Klasse QSize (siehe Kapitel 17) zurück, das Breite und Höhe des Widgets speichert.

Größe und Koordinaten eines Qt-Widgets im übergeordneten Bereich
Abb. 5.3. Widget im Bildschimbereich (oder des Vorgängers)

Die Methoden x(), y() und pos() dienen zur Bestimmung der Koordinaten des Widgets. Die ersten beiden Methoden geben ganzzahlige Koordinatenwerte entlang der Achsen X und Y zurück, die Methode pos() ein Objekt der Klasse QPoint (siehe Kapitel 17), das beide Koordinaten speichert.

Die Methode geometry() gibt ein Objekt der Klasse QRect (siehe Kapitel 17) zurück, das Position und Abmessungen des Widgets beschreibt.

Die Position des Widgets kann mit der Methode move() und seine Abmessungen mit der Methode resize() geändert werden. Zum Beispiel:

pwgt->move(5, 5);
pwgt->resize(260, 330);

Position und Abmessungen des Widgets können gleichzeitig durch Aufruf der Methode setGeometry() geändert werden. Der erste Parameter dieser Methode legt die Koordinate der oberen linken Ecke des Widgets entlang der Achse X fest, der zweite entlang der Achse Y, der dritte legt die Breite und der vierte die Höhe fest. Zum Beispiel ist der folgende Aufruf äquivalent zu den beiden zuvor angegebenen Aufrufen move() und resize():

pwgt->setGeometry(5, 5, 260, 330);

Mechanismus der Hintergrundspeicherung

Die Technik der Hintergrundspeicherung (Backing Store) besteht darin, Rasterbilder für alle Widgets eines Fensters jederzeit im Computerspeicher zu speichern, was es ermöglicht, den benötigten Teil des gespeicherten Bereichs sehr schnell zu platzieren, ohne dass das System Zeichenereignisse (PaintEvent) aufruft. Dabei spielt es keine Rolle, wie komplex das Zeichnen des Widgets selbst ist.

Der Aufruf eines Zeichenereignisses für ein Widget erfolgt nur in den Fällen, in denen dies wirklich notwendig ist – beispielsweise zum Ändern des Hintergrunds. Diese Technik ermöglicht eine erhebliche Leistungssteigerung.

Festlegen des Widget-Hintergrunds

Einem Widget kann ein Hintergrund zugewiesen werden, wobei dies eine Farbe oder ein Rasterbild sein kann. Zum Füllen mit einer Volltonfarbe oder einem Rasterbild muss zunächst ein Palette-Objekt erstellt werden (siehe Kapitel 13), das dann durch Aufruf der Methode setPalette() im Widget gesetzt wird.

Das Widget verfügt über eine wichtige Eigenschaft autoFillBackground, die standardmäßig auf false gesetzt ist. Infolgedessen werden alle Nachkommen des Widgets nicht mit einem Hintergrund gefüllt und sind entsprechend unsichtbar. Wenn Sie diese Eigenschaft auf true setzen, zwingen Sie das Widget, den Hintergrund automatisch zu füllen, was es sichtbar macht. Zum Beispiel:

wgt.setAutoFillBackground(true);

In Listing 5.1 wird ein Widget der obersten Ebene wgt erstellt, das zwei anderen Widgets (Zeiger pwgt1 und pwgt2) als Vorgänger übergeben wird.

Listing 5.1. Erstellen eines Widgets der obersten Ebene (Datei main.cpp)

#include <QApplication>
#include <QWidget>
#include <QPixmap>

int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    QWidget      wgt;

    auto* pwgt1 = new QWidget(&wgt);
 QPalette pal1;
    pal1.setColor(pwgt1->backgroundRole(), Qt::blue);
    pwgt1->setPalette(pal1);
    pwgt1->resize(128, 128);
    pwgt1->move(40, 40);
    pwgt1->setAutoFillBackground(true);

    auto* pwgt2 = new QWidget(&wgt);
 QPalette pal2;
    pal2.setBrush(pwgt2->backgroundRole(), QBrush(QPixmap(":/crocodile.jpg")));
 pwgt2->setPalette(pal2);
    pwgt2->resize(128, 128);
    pwgt2->move(90, 90);
    pwgt2->setAutoFillBackground(true);

    wgt.resize(250, 250);
    wgt.show();

    return app.exec();
}

Dem ersten Kind-Widget wird ein Palettenobjekt über setPalette() zugewiesen, das eine einfarbige Hintergrundfarbe (blau) festlegt. Nach der Größenänderung mit resize() und dem Verschieben innerhalb des übergeordneten Widgets mit move() setzt die Methode setAutoFillBackground() die Eigenschaft autoFillBackground auf true, sodass das Widget sichtbar wird.

Zwei Qt-Widgets mit unterschiedlichem Hintergrund – Farbe und Rasterbild
Abb. 5.4. Widgets mit unterschiedlichen Hintergründen

Die gleichen Operationen werden am zweiten Kind-Widget (Zeiger pwgt2) durchgeführt. Der Unterschied besteht darin, dass das zweite Widget ein Rasterbild verwendet, das aus stone.jpg geladen und über das Palettenobjekt pal2 als Hintergrund angewendet wird. Als Ergebnis wird ein Widget mit einer einfarbigen Fläche und das andere mit einem Rasterbild gefüllt (Abb. 5.4).

Ändern des Mauszeigers

Die Mauszeigerklasse QCursor ist in der Header-Datei QCursor definiert. Der Zeiger ist ein kleines Rasterbild, das die aktuelle Mausposition auf dem Bildschirm anzeigt. Sein Erscheinungsbild kann sich je nach Position ändern. In den meisten Fällen ist es ein Pfeil, aber beim Überfahren eines Fensterrahmens kann er sich in einen doppelt gerichteten Pfeil ändern, was anzeigt, dass das Fenster in der Größe verändert werden kann.

Sie können das Zeigerbild setzen, indem Sie setCursor() aufrufen und einen der CursorShape-Werte aus dem Qt-Namensraum übergeben, wie in Tabelle 5.1 aufgeführt.

Tabelle 5.1. Qt-Namensraum CursorShape-Werte

Wert Beschreibung Aussehen
ArrowCursor Standard-Pfeilcursor. Erscheint über den meisten Widgets. Wird zum Zeigen, Auswählen oder Verschieben von Objekten verwendet.
UpArrowCursor Nach oben gerichteter Pfeil. Die Verwendung hängt vom Kontext ab.
CrossCursor Fadenkreuz-Cursor. Wird zum Auswählen rechteckiger Bereiche verwendet. Kann über jedem Widget erscheinen, das diese Operation unterstützt.
WaitCursor Wartecursor. Erscheint über jedem Widget oder an jeder Position, während eine Hintergrundoperation ausgeführt wird.
IbeamCursor I-Beam-Textcursor (senkrechte Linie). Erscheint über Text, um Bearbeitung, Auswahl oder Einfügen anzuzeigen.
PointingHandCursor Handcursor. Erscheint über Hyperlinks.
ForbiddenCursor Verboten“-Cursor. Erscheint über einem Zielbereich während Drag-and-Drop-Vorgängen und zeigt an, dass das Ziel das gezogene Element nicht akzeptieren kann.
WhatsThisCursor Fragezeichen-Cursor. Erscheint über den meisten Widgets, um kontextsensitive Hilfe aufzurufen.
SizeVerCursor Vertical resize cursor. Appears over a vertically resizable window border.
SizeHorCursor Horizontaler Größenänderungs-Cursor. Erscheint am Rand eines horizontal skalierbaren Fensters.
SizeBDiagCursor Diagonaler Größenänderungs-Cursor (eine Richtung). Erscheint am Rand eines diagonal skalierbaren Fensters.
SizeFDiagCursor Diagonaler Größenänderungs-Cursor (andere Richtung). Erscheint am Rand eines diagonal skalierbaren Fensters.
SizeAllCursor Verschiebecursor. Zeigt an, dass das Fenster verschoben werden kann.
SplitVCursor Vertikaler Split-Cursor. Erscheint am Rand zwischen zwei vertikal geteilten Widgets. Siehe Kapitel 6 für Details zu Widget-Splittern.
SplitHCursor Horizontaler Split-Cursor. Erscheint am Rand zwischen zwei horizontal geteilten Widgets. Siehe Kapitel 6 für Details zu Widget-Splittern.
OpenHandCursor Offene-Hand-Cursor. Zeigt an, dass der Inhalt im Anzeigebereich verschoben (verschoben/gescrollt) werden kann.
ClosedHandCursor Geschlossene-Hand-Cursor. Zeigt an, dass der Inhalt im Anzeigebereich gerade verschoben wird.
BlankCursor Unsichtbarer Cursor. Zeigt an, dass keine Mausinteraktion möglich ist.

Die Klasse QCursor stellt eine pos()-Methode bereit, die die aktuelle Zeigerposition relativ zur oberen linken Ecke des Bildschirms zurückgibt. Der Zeiger kann programmatisch mit setPos() bewegt werden.

Setzen des Zeigers für die gesamte Anwendung

Der Aufruf der statischen Methode QGuiApplication::setOverrideCursor() setzt das Zeigerbild für die gesamte Anwendung. Dies kann nützlich sein, um dem Benutzer mitzuteilen, dass die Anwendung eine aufwendige, lang andauernde Operation ausführt und nicht auf Eingaben reagieren kann. Während dieser Zeit sollten alle Widgets einen Wartezeiger anzeigen, was durch den Aufruf von QGuiApplication::setOverrideCursor(Qt::WaitCursor) erreicht wird. Sobald die Anwendung wieder bereit ist, Benutzereingaben zu akzeptieren, stellt der Aufruf der statischen Methode QGuiApplication::restoreOverrideCursor() den Zeiger auf sein vorheriges Erscheinungsbild zurück.

Um ein benutzerdefiniertes Zeigerbild zu erstellen, benötigen Sie zwei QBitmap-Rasterbilder derselben Größe, von denen eines als Bitmaske dient. Dort, wo die Maske die Farbe color1 hat, wird das Zeigerbild gezeichnet; dort, wo die Maske die Farbe color0 hat, ist das Bild transparent.

Ein einfacherer Ansatz ist die Verwendung eines QPixmap-Objekts. Die Ausgabe des Programms in Listing 5.2 (siehe Abb. 5.5) demonstriert diese Fähigkeit.

Benutzerdefinierter Mauszeiger aus einem QPixmap-Bild in Qt
Abb. 5.5. Verwendung eines benutzerdefinierten Bildes für den Mauszeiger

Listing 5.2. Ändern des Mauszeigers

#include <QApplication>
#include <QWidget>

int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    QWidget      wgt;
    QPixmap      pix(":/cursor.png");
    QCursor      cur(pix);

    wgt.setCursor(cur);
    wgt.resize(180, 100);
    wgt.show();

    return app.exec();
}

Im Listing 5.2 wird zunächst ein Widget wgt erstellt, dann ein QPixmap-Objekt pix, dessen Konstruktor den Namen einer PNG-Datei erhält, die sowohl das Rasterbild als auch seine Bitmaske enthält (eine detaillierte Beschreibung dieses Formats und der Fähigkeiten der QPixmap-Klasse finden Sie in Kapitel 19). Um den Zeiger zu erstellen, wird das Pixmap-Objekt an den QCursor-Konstruktor übergeben, und der resultierende Zeiger wird über setCursor() auf das Widget angewendet.

Gestapelte Widgets

Die QStackedWidget-Klasse erbt von QFrame und repräsentiert ein Widget, das jeweils nur eines seiner untergeordneten Elemente anzeigt.

Widgets werden mit addWidget() zum Stapel hinzugefügt. Diese Funktion akzeptiert einen Zeiger auf ein Widget und gibt eine ganzzahlige Kennung zurück, die diesem Widget zugewiesen wird. Widgets werden aus dem Stapel entfernt, indem removeWidget() mit einem Zeiger auf das Widget aufgerufen wird.

Um ein bestimmtes Widget sichtbar zu machen, übergeben Sie einen Zeiger darauf an den Slot setCurrentWidget(), oder übergeben Sie seine Kennung an den Slot setCurrentIndex(). Die Kennung eines Widgets kann durch Aufruf von indexOf() mit einem Zeiger auf das Widget abgerufen werden.

Rahmen-Widget

Die QFrame-Klasse erbt von QWidget und erweitert diese um die Fähigkeit, einen Rahmen darzustellen. Sie dient als Basisklasse für eine große Anzahl von Widget-Klassen (siehe Abb. 5.1). Der Rahmenstil kann mit setFrameStyle() angepasst werden, wobei eine Kombination aus Form-Flags und Schatten-Flags verwendet wird, die mit dem bitweisen ODER-Operator | verknüpft werden.

Es gibt drei Schatten-Flags (Tabelle 5.2): QFrame::Raised, QFrame::Plain und QFrame::Sunken. Diese erzeugen einen abgeschrägten oder flachen visuellen Effekt auf dem Rahmen.

Tabelle 5.2. Rahmenbeispiele

Flags Aussehen
Box | Plain
Box | Raised
Box | Sunken
Panel | Plain
Panel | Raised
Panel | Sunken
WinPanel | Plain
WinPanel | Raised
WinPanel | Sunken
HLine | Plain
HLine | Raised
HLine | Sunken
VLine | Plain
VLine | Raised
VLine | Sunken
StyledPanel | Plain
StyledPanel | Raised
StyledPanel | Sunken

Fünf primäre Form-Flags stehen zur Verfügung, um das Erscheinungsbild des Rahmens zu definieren (siehe Tabelle 5.2): QFrame::Box, QFrame::Panel, QFrame::WinPanel, QFrame::HLine und QFrame::VLine. Wenn überhaupt kein Rahmen angezeigt werden soll, übergibt man QFrame::NoFrame an setFrameStyle().

Die Methode setContentsMargin() der Klasse QWidget legt den Abstand zwischen Rahmen und Widget-Inhalt fest. Mit den Methoden setLineWidth() und setMidLineWidth() von QFrame wird die Rahmenstärke selbst gesteuert:

auto* pfrm = new QFrame;
pfrm->setFrameStyle(QFrame::Box | QFrame::Sunken);
pfrm->setLineWidth(3);

In diesem Beispiel wird ein Rahmen-Widget erstellt, der gewünschte Rahmenstil mit setFrameStyle() festgelegt und die Rahmenstärke mit setLineWidth() eingestellt.

Widget für scrollbare Ansicht

Die Basisklasse für scrollbare Ansichten, QAbstractScrollArea, ist von der Klasse QFrame abgeleitet und stellt ein Fenster dar, um nur einen Teil der Informationen anzuzeigen. Das Widget für scrollbare Ansicht selbst wird von der Klasse QScrollArea implementiert.

Dieses Widget kann Nachkommen-Widgets aufnehmen, und wenn mindestens eines davon über die Grenzen des Ansichtsfensters hinausgeht, erscheinen automatisch vertikale und/oder horizontale Bildlaufleisten. Mit ihrer Hilfe können Teile des Widgets in den Anzeigebereich verschoben werden.

Wenn Sie möchten, dass die Bildlaufleisten immer sichtbar sind, müssen Sie den Wert Qt::ScrollBarAlwaysOn an die Methoden zur Steuerung des Bildlaufleistenverhaltens übergeben. Zum Beispiel:

QScrollArea sa;
sa.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
sa.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);

Wie aus Abb. 5.6 ersichtlich ist, ist das Widget für scrollbare Ansicht eine Kombination aus mehreren Widgets, die zusammenarbeiten. Zeiger auf diese Widgets können mit den in der Abbildung angegebenen Methoden abgerufen werden. Der Zugriff auf das Widget des Anzeigebereichs erfolgt über die Methode QAbstractScrollArea::viewport(). Die Methoden verticalScrollBar() und horizontalScrollBar() geben Zeiger auf die Widgets der vertikalen bzw. horizontalen Bildlaufleiste der Klasse QScrollBar zurück. Die Methode cornerWidget() gibt einen Zeiger auf das Widget zurück, das sich in der unteren rechten Ecke befindet.

Aufbau eines QScrollArea-Widgets mit Viewport und Bildlaufleisten
Abb. 5.6. Struktur des Widgets für scrollbare Ansicht

Ein Widget kann im Widget für scrollbare Ansicht mithilfe der Methode setWidget() gesetzt werden, indem ein Zeiger darauf übergeben wird. Dieser Vorgang macht das übergebene Widget automatisch zum Nachkommen des Widgets des Anzeigebereichs. Der Zeiger auf das gesetzte Widget kann jederzeit mit der Methode widget() abgerufen werden. Das Entfernen eines Widgets aus QScrollArea erfolgt durch Aufruf der Methode removeChild().

Erläuterung zur Objekthierarchie

Wenn wir sagen, dass der Vorgang „das übergebene Widget automatisch zum Nachkommen des Widgets des Anzeigebereichs macht” im Kontext von QScrollArea, meinen wir die Objekthierarchie. Das bedeutet, dass das Widget zu einem untergeordneten Objekt für viewport() des Scroll-Bereichs wird, nicht dass es im Sinne von Klassen davon erbt.

Beispielanwendung mit scrollbarer Bildanzeige in Qt (QScrollArea)
Abb. 5.7. Beispiel für ein Widget mit scrollbarer Ansicht

Abb. 5.7 zeigt das Ergebnis der Programmausführung zur Anwendung der scrollbaren Ansicht (Listing 5.3). Das Programm ermöglicht es, Teile des Bildes in den sichtbaren Bereich des Fensters zu verschieben.

Listing 5.3. Anwendung der scrollbaren Ansicht (Datei main.cpp)

#include <QApplication>
#include <QScrollArea>
#include <QWidget>

int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    QScrollArea  sa;

    auto*   pwgt = new QWidget;
    QPixmap pix(":/img.jpg");

    QPalette pal;
    pal.setBrush(pwgt->backgroundRole(), QBrush(pix));
    pwgt->setPalette(pal);
    pwgt->setAutoFillBackground(true);
    pwgt->setFixedSize(pix.width(), pix.height());

    sa.setWidget(pwgt);
    sa.resize(350, 150);
    sa.show();

    return app.exec();
}

In Listing 5.3 werden zunächst das Widget für scrollbare Ansicht sa, ein normales Widget (Zeiger pwgt) und ein Rasterbild-Objekt pix erstellt. Das Rasterbild-Objekt wird mit der Datei img.jpg initialisiert, die dann durch Aufruf der Methode setPalette() als Hintergrund des Widgets gesetzt wird. Damit das Widget sichtbar ist, aktiviert die Methode setAutoFillBackground() den Modus zur automatischen Hintergrundfüllung. Die Abmessungen des Widgets (Zeiger pwgt) werden durch Aufruf der Methode setFixedSize() an die Abmessungen des Rasterbildes angepasst. Abschließend fügt das Widget für scrollbare Ansicht sa durch Aufruf der Methode setWidget() das von uns erstellte Widget in sein Fenster ein.

Zusammenfassung

Im Zentrum der Erstellung von Benutzeroberflächen steht das Konzept Widget (Steuerelement). Die Klasse QWidget ist die Basisklasse für alle Steuerelemente. Alles, woraus die Benutzeroberfläche in Qt-Anwendungen hauptsächlich besteht, sind Objekte der Klasse QWidget und davon abgeleiteter Klassen.

Es gibt keine Trennung zwischen Container-Widgets und einfachen Widgets – jedes Widget kann als Container für andere Widgets verwendet werden. Zu den grundlegenden Operationen mit Widgets gehören neben Anzeigen (show) und Verbergen (hide) Methoden zum Ändern ihrer Größe und Position.

Die Position und Abmessungen von Widgets innerhalb des Vorgänger-Widgets können bei Verwendung von Layout-Klassen automatisch festgelegt werden.

Widgets der obersten Ebene haben ihr eigenes Fenster, das auf unterschiedliche Weise dekoriert werden kann – beispielsweise durch Ändern des Fensterrahmens.

In jedem Widget können Mauszeiger festgelegt werden. Qt bietet eine Reihe vordefinierter Bilder solcher Zeiger, die zur Festlegung verwendet werden können. Es besteht auch die Möglichkeit, eigene Zeiger aus Rasterbildern zu erstellen.

Die Klasse QFrame ist von der Klasse QWidget abgeleitet und stellt ein Rechteck mit einem Rahmen dar, dessen Stil geändert werden kann.

Die Klasse QStackedWidget zeigt zu einem bestimmten Zeitpunkt nur eines ihrer Kind-Widgets an. Diese Eigenschaft wird verwendet, wenn es viele Widgets gibt und nur eines zu einer bestimmten Zeit sichtbar sein soll.

Das Widget für scrollbare Ansicht bietet ein Fenster zum Anzeigen nur eines Teils der Informationen. Dieses Widget wird verwendet, um Informationen anzuzeigen, deren Abmessungen den für sie zugewiesenen Anzeigebereich überschreiten.


Schöpfen Sie das Potenzial dieses Kapitels voll aus! Erhalten Sie vorbereitete Zusatzmaterialien dafür. Stellen Sie Fragen, teilen Sie Ihre Erfahrungen oder nehmen Sie einfach an der Diskussion unter folgendem Link teil: https://qt-book.com/05-69-de/

Leave a Reply

Your email address will not be published. Required fields are marked *