Sur cette page

Exemple de fenêtre matricielle

Cet exemple montre comment créer une application minimale basée sur QWindow en utilisant QPainter pour le rendu.

Point d'entrée de l'application

int main(int argc, char **argv)
{
    QGuiApplication app(argc, argv);

    RasterWindow window;
    window.show();

    return app.exec();
}

Le point d'entrée d'une application basée sur QWindow est la classe QGuiApplication. Elle gère le flux de contrôle et les paramètres principaux de l'application GUI. Nous passons les arguments de la ligne de commande qui peuvent être utilisés pour sélectionner certaines options du système.

Ensuite, nous créons notre instance de fenêtre et appelons la fonction QWindow::show() pour indiquer au système de fenêtrage que cette fenêtre doit maintenant être visible à l'écran.

Une fois cela fait, nous entrons dans la boucle d'événements de l'application pour que celle-ci puisse s'exécuter.

Déclaration de 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;
};

Nous commençons par inclure l'en-tête <QtGui>. Cela signifie que nous pouvons utiliser toutes les classes du module Qt GUI. Les classes peuvent également être incluses individuellement si cela est préférable.

La classe RasterWindow sous-classe directement QWindow et fournit un constructeur qui permet à la fenêtre d'être une sous-fenêtre d'une autre QWindow. Les QWindows sans parents apparaissent dans le système de fenêtrage comme des fenêtres de premier niveau.

La classe déclare un QBackingStore que nous utilisons pour gérer le tampon arrière de la fenêtre pour les graphiques basés sur QPainter.

La fenêtre matricielle est également réutilisée dans quelques autres exemples et ajoute quelques fonctions d'aide, comme renderLater().

Implémentation de RasterWindow

RasterWindow::RasterWindow(QWindow *parent)
    : QWindow(parent)
    , m_backingStore(new QBackingStore(this))
{
    setGeometry(100, 100, 300, 200);
}

Dans le constructeur, nous créons le backingstore et lui passons l'instance de fenêtre qu'il est censé gérer. Nous définissons également la géométrie initiale de la fenêtre.

void RasterWindow::exposeEvent(QExposeEvent *)
{
    if (isExposed())
        renderNow();
}

Peu après avoir appelé QWindow::show() sur une fenêtre créée, la fonction virtuelle QWindow::exposeEvent() sera appelée pour nous informer que l'exposition de la fenêtre dans le système de fenêtrage a changé. L'événement contient la sous-région exposée, mais comme nous dessinerons de toute façon la fenêtre entière à chaque fois, nous n'en ferons pas usage.

La fonction QWindow::isExposed() nous indique si la fenêtre est affichée ou non. Nous en avons besoin car l'événement exposeEvent est également appelé lorsque la fenêtre est masquée dans le système de fenêtrage. Si la fenêtre est affichée, nous appelons renderNow() pour dessiner la fenêtre immédiatement. Nous voulons dessiner tout de suite pour pouvoir présenter au système un contenu visuel.

void RasterWindow::resizeEvent(QResizeEvent *resizeEvent)
{
    m_backingStore->resize(resizeEvent->size());
}

L'événement resize est garanti d'être appelé avant que la fenêtre ne soit affichée à l'écran et sera également appelé chaque fois que la fenêtre est redimensionnée à l'écran. Nous l'utilisons pour redimensionner le tampon arrière et reporter le rendu à l'événement expose correspondant/suivant.

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);
}

La fonction renderNow met en place ce qui est nécessaire pour qu'une fenêtre QWindow rende son contenu à l'aide de QPainter. Comme les fenêtres obscurcies ne seront pas visibles, nous abandonnons si la fenêtre n'est pas exposée dans le système de fenêtrage. Cela peut par exemple se produire lorsqu'une autre fenêtre masque complètement cette fenêtre.

Nous commençons le dessin en appelant QBackingStore::beginPaint() sur la région que nous voulons dessiner. Ensuite, nous obtenons le QPaintDevice du tampon arrière et créons un QPainter pour effectuer le rendu sur ce périphérique de peinture.

Pour éviter de laisser des traces du rendu précédent et commencer avec un tampon propre, nous remplissons tout le tampon avec la couleur blanche. Nous appelons ensuite la fonction virtuelle render() qui effectue le dessin de cette fenêtre.

Une fois le dessin terminé, nous appelons endPaint() pour signaler que le rendu est terminé et présentons le contenu du tampon arrière à l'aide de QBackingStore::flush().

void RasterWindow::render(QPainter *painter)
{
    painter->drawText(QRectF(0, 0, width(), height()), Qt::AlignCenter, QStringLiteral("QWindow"));
}

La fonction de rendu contient le code de dessin de la fenêtre. Dans cet exemple minimal, nous ne dessinons que la chaîne de caractères "QWindow" au centre.

Rendu asynchrone

void RasterWindow::renderLater()
{
    requestUpdate();
}

Nous avons passé en revue quelques endroits où la fenêtre devait être repeinte immédiatement. Dans certains cas, ce n'est pas souhaitable, mais il vaut mieux laisser l'application retourner dans la boucle d'événements et programmer le repeint pour plus tard. Nous y parvenons en demandant une mise à jour, à l'aide de QWindow::requestUpdate(), qui sera délivrée lorsque le système sera prêt à repeindre.

bool RasterWindow::event(QEvent *event)
{
    if (event->type() == QEvent::UpdateRequest) {
        renderNow();
        return true;
    }
    return QWindow::event(event);
}

Nous réimplémentons la fonction virtuelle QObject::event() pour gérer l'événement de mise à jour. Lorsque l'événement arrive, nous appelons renderNow() pour effectuer le rendu de la fenêtre immédiatement.

Exemple de projet @ code.qt.io

© 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.