Beispiel für ein Rasterfenster
Dieses Beispiel zeigt, wie man eine minimale, auf „ QWindow “ basierende Anwendung erstellt, die „ QPainter “ für die Darstellung nutzt.
Einstiegspunkt der Anwendung
int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
RasterWindow window;
window.show();
return app.exec();
}Der Einstiegspunkt für eine auf „ QWindow “ basierende Anwendung ist die Klasse „ QGuiApplication “. Sie verwaltet den Kontrollfluss und die Haupteinstellungen der GUI-Anwendung. Wir übergeben die Befehlszeilenargumente, mit denen bestimmte systemweite Optionen abgerufen werden können.
Anschließend erstellen wir unsere Fensterinstanz und rufen dann die Funktion ` QWindow::show()` auf, um dem Fenstersystem mitzuteilen, dass dieses Fenster nun auf dem Bildschirm angezeigt werden soll.
Sobald dies geschehen ist, treten wir in die Ereignisschleife der Anwendung ein, damit die Anwendung ausgeführt werden kann.
Deklaration von „RasterWindow“
#include <QtGui>
#include <QScopedPointer>
class RasterWindow : public QWindow
{
Q_OBJECT
public:
explicit RasterWindow(QWindow *parent = nullptr);
virtual void render(QPainter *painter);
public slots:
void renderLater();
void renderNow();
protected:
bool event(QEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
void exposeEvent(QExposeEvent *event) override;
private:
QScopedPointer<QBackingStore> m_backingStore;
};Zunächst binden wir den Header „ <QtGui> “ ein. Damit stehen uns alle Klassen des Moduls „ Qt GUI “ zur Verfügung. Klassen können bei Bedarf auch einzeln eingebunden werden.
Die Klasse `RasterWindow` ist eine direkte Unterklasse von ` QWindow ` und verfügt über einen Konstruktor, der es ermöglicht, das Fenster als Unterfenster eines anderen ` QWindow` zu verwenden. QWindows ohne übergeordnetes Fenster werden im Fenstersystem als Fenster der obersten Ebene angezeigt.
Die Klasse deklariert ein ` QBackingStore `, das wir zur Verwaltung des Backbuffers des Fensters für ` QPainter `-basierte Grafiken verwenden.
Das Rasterfenster wird auch in einigen anderen Beispielen wiederverwendet und enthält einige Hilfsfunktionen wie z. B. `renderLater()`.
Implementierung von `RasterWindow`
RasterWindow::RasterWindow(QWindow *parent)
: QWindow(parent)
, m_backingStore(new QBackingStore(this))
{
setGeometry(100, 100, 300, 200);
}Im Konstruktor erstellen wir den Backingstore und übergeben ihm die Fensterinstanz, die er verwalten soll. Außerdem legen wir die anfängliche Fenstergeometrie fest.
void RasterWindow::exposeEvent(QExposeEvent *)
{
if (isExposed())
renderNow();
}Kurz nach dem Aufruf von ` QWindow::show()` für ein erstelltes Fenster wird die virtuelle Funktion ` QWindow::exposeEvent()` aufgerufen, um uns mitzuteilen, dass sich die Sichtbarkeit des Fensters im Fenstersystem geändert hat. Das Ereignis enthält den sichtbaren Teilbereich, doch da wir ohnehin jedes Mal das gesamte Fenster zeichnen, nutzen wir diese Information nicht.
Die Funktion ` QWindow::isExposed()` teilt uns mit, ob das Fenster sichtbar ist oder nicht. Dies benötigen wir, da `exposeEvent` auch dann aufgerufen wird, wenn das Fenster im Fenstersystem verdeckt wird. Ist das Fenster sichtbar, rufen wir `renderNow()` auf, um das Fenster sofort zu zeichnen. Wir möchten sofort zeichnen, damit wir dem System visuelle Inhalte präsentieren können.
void RasterWindow::resizeEvent(QResizeEvent *resizeEvent)
{
m_backingStore->resize(resizeEvent->size());
}Das „resize“-Ereignis wird garantiert aufgerufen, bevor das Fenster auf dem Bildschirm angezeigt wird, und wird auch immer dann aufgerufen, wenn die Größe des Fensters auf dem Bildschirm geändert wird. Wir nutzen dies, um die Größe des Backbuffers anzupassen und das Rendern auf das entsprechende bzw. nachfolgende „expose“-Ereignis zu verschieben.
void RasterWindow::renderNow()
{
if (!isExposed())
return;
QRect rect(0, 0, width(), height());
m_backingStore->beginPaint(rect);
QPaintDevice *device = m_backingStore->paintDevice();
QPainter painter(device);
painter.fillRect(0, 0, width(), height(), QGradient::NightFade);
render(&painter);
painter.end();
m_backingStore->endPaint();
m_backingStore->flush(rect);
}Die Funktion `renderNow` bereitet mit ` QPainter` alles vor, was für ein „ QWindow “ zum Rendern seines Inhalts erforderlich ist. Da verdeckte Fenster nicht sichtbar sind, brechen wir den Vorgang ab, wenn das Fenster im Fenstersystem nicht sichtbar ist. Dies kann beispielsweise passieren, wenn ein anderes Fenster dieses Fenster vollständig verdeckt.
Wir beginnen das Zeichnen, indem wir ` QBackingStore::beginPaint()` für den Bereich aufrufen, den wir zeichnen möchten. Anschließend rufen wir die ` QPaintDevice ` des Backbuffers ab und erstellen ein ` QPainter `, um auf dieses Zeichengerät zu rendern.
Um zu verhindern, dass Spuren des vorherigen Renderings zurückbleiben, und mit einem leeren Puffer zu beginnen, füllen wir den gesamten Puffer mit der Farbe Weiß. Anschließend rufen wir die virtuelle Funktion `render()` auf, die das eigentliche Zeichnen dieses Fensters übernimmt.
Nachdem das Zeichnen abgeschlossen ist, rufen wir `endPaint()` auf, um zu signalisieren, dass wir mit dem Rendern fertig sind, und präsentieren den Inhalt im Backbuffer mithilfe von ` QBackingStore::flush()`.
void RasterWindow::render(QPainter *painter)
{
painter->drawText(QRectF(0, 0, width(), height()), Qt::AlignCenter, QStringLiteral("QWindow"));
}Die Funktion `render` enthält den Zeichencode für das Fenster. In diesem Minimalbeispiel zeichnen wir lediglich die Zeichenkette „QWindow “ in der Mitte.
Asynchrones Rendern
void RasterWindow::renderLater()
{
requestUpdate();
}Wir haben einige Stellen betrachtet, an denen das Fenster sofort neu gezeichnet werden musste. Es gibt jedoch Fälle, in denen dies nicht wünschenswert ist, sondern die Anwendung stattdessen zur Ereignisschleife zurückkehren und die Neugezeichnung für später einplanen soll. Dies erreichen wir, indem wir mit ` QWindow::requestUpdate()` eine Aktualisierung anfordern, die dann ausgeführt wird, sobald das System bereit ist, das Fenster neu zu zeichnen.
bool RasterWindow::event(QEvent *event)
{
if (event->type() == QEvent::UpdateRequest) {
renderNow();
return true;
}
return QWindow::event(event);
}Wir implementieren die virtuelle Funktion ` QObject::event()` neu, um das Update-Ereignis zu verarbeiten. Wenn das Ereignis eintrifft, rufen wir `renderNow()` auf, um das Fenster sofort neu zu zeichnen.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.