Qt Canvas Painter - Exemple « Hello Widget »

Illustre l'utilisation de QCanvasPainter et QCanvasPainterWidget.

Fenêtre principale comportant un widget enfant affichant le texte « Hello Qt Canvas Painter » et un cœur vert à motifs sur un dégradé radial

Cet exemple implémente une sous-classe de ` QCanvasPainterWidget `. Une ou plusieurs instances de ce widget peuvent ensuite être ajoutées à un ` QMdiArea ` au sein de ` QMainWindow`.

QCanvasPainterWidget Ce dernier dérive lui-même de ` QRhiWidget` et utilise toujours le rendu 3D accéléré via ` QRhi`.

Les sous-classes de ` QCanvasPainterWidget ` devront au minimum implémenter la méthode ` paint()`. Cet exemple utilise également une image, chargée à partir d’un fichier PNG.

class CanvasWidget : public QCanvasPainterWidget
{
public:
    CanvasWidget();
    void initializeResources(QCanvasPainter *p) override;
    void paint(QCanvasPainter *p) override;
    void graphicsResourcesInvalidated() override;

private:
    QCanvasImage m_image;
};

La fonction paint() peut commencer immédiatement à dessiner en utilisant le fournisseur QCanvasPainter:

void CanvasWidget::paint(QCanvasPainter *p)
{
    const float size = std::min(width(), height());
    const float centerX = width() / 2;
    const float centerY = height() / 2;

    // Paint the background circle
    QCanvasRadialGradient gradient1(centerX, centerY - size * 0.1f, 0, size * 0.6f);
    gradient1.setStartColor(QColor(0x909090));
    gradient1.setEndColor(QColor(0x404040));
    p->beginPath();
    p->circle(QPointF(centerX, centerY), size * 0.46f);
    p->setFillStyle(gradient1);
    p->fill();
    p->setStrokeStyle(QColor(0x202020));
    p->setLineWidth(size * 0.02f);
    p->stroke();

Consultez QCanvasPainter, QCanvasBrush, QCanvasRadialGradient, QCanvasImagePattern, QCanvasImage et QFont pour plus d’informations sur les fonctionnalités utilisées dans cet exemple.

L'image sert de motif pour remplir la forme de cœur :

    // Paint heart
    QCanvasImagePattern pattern(m_image, centerX, centerY, size * 0.08f, size * 0.05f);
    p->setFillStyle(pattern);

Lorsque des ressources telles que QCanvasImage et QCanvasOffscreenCanvas sont impliquées, celles-ci sont gérées dans les méthodes initializeResources() et graphicsResourcesInvalidated() :

void CanvasWidget::initializeResources(QCanvasPainter *p)
{
    Q_ASSERT(m_image.isNull());
    const auto flags = QCanvasPainter::ImageFlag::Repeat | QCanvasPainter::ImageFlag::GenerateMipmaps;
    m_image = p->addImage(QImage(u":/qt-translucent.png"_s), flags);
}

void CanvasWidget::graphicsResourcesInvalidated()
{
    m_image = {};
}

initializeResources() est simplement une fonction de commodité. Au lieu de l'implémenter, on pourrait également écrire ce qui suit dans paint():

if (m_image.isNull())
    m_image = p->addImage(QImage(":/qt-translucent.png"), QCanvasPainter::ImageFlag::Repeat);

Cet exemple ne modifie pas la parenté des widgets entre les fenêtres ; les ressources graphiques ne seront donc pas perdues. Il est néanmoins recommandé d’attribuer un objet vide par défaut à toutes les variables QCanvasImage et QCanvasOffscreenCanvas dans la méthode graphicsResourcesInvalidated().

La fonction `main()` crée un ` QMainWindow ` et un ` QMdiArea`. Plusieurs instances de la classe `CanvasWidget` peuvent être ajoutées en tant que sous-fenêtres. Comme la valeur par défaut de ` hasSharedPainter()` est `true` et qu’elles sont placées au sein du même widget de niveau supérieur, tous les widgets de dessin partageront le même ` QCanvasPainter ` et l’infrastructure de rendu associée, au lieu d’en créer des dédiés.

Exemple de projet sur 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.