Qt Canvas Painter - Exemple de widget Hello

Démontre l'utilisation de QCanvasPainter et QCanvasPainterWidget.

L'exemple met en œuvre une sous-classe de QCanvasPainterWidget. Une ou plusieurs instances de ce widget peuvent ensuite être ajoutées à un QMdiArea à l'intérieur du QMainWindow.

QCanvasPainterWidget QRhiWidget est lui-même dérivé de et utilise toujours un rendu 3D accéléré via QRhi.

Les sous-classes de QCanvasPainterWidget devront au minimum implémenter 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 à dessiner en utilisant le fournisseur QCanvasPainter immédiatement :

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, 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();

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

L'image est utilisée comme modèle pour remplir la forme du 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, elles sont gérées dans 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() n'est qu'une commodité. Au lieu de l'implémenter, on pourrait aussi écrire ce qui suit dans paint() :

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

Cet exemple ne répartit pas les widgets entre les fenêtres, de sorte que les ressources graphiques ne seront pas perdues. C'est néanmoins un bon modèle que d'affecter un objet vide par défaut à toutes les variables QCanvasImage et QCanvasOffscreenCanvas dans graphicsResourcesInvalidated().

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

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.