Qt Canvas Painter - Hello Widget Example
Demonstrates the use of QCPainter and QCPainterWidget.

The example implements a QCPainterWidget subclass. One or more instances of this widget can then be added into a QMdiArea inside the QMainWindow.
QCPainterWidget itself derives from QRhiWidget, and is always using accelerated 3D rendering via QRhi.
Subclasses of QCPainterWidget will at minimum want to implement paint(). This example also uses an image, loaded from a PNG file.
class CanvasWidget : public QCPainterWidget { public: CanvasWidget(); void initializeResources(QCPainter *p) override; void paint(QCPainter *p) override; void graphicsResourcesInvalidated() override; private: QCImage m_image; };
The paint() function can start drawing using the provider QCPainter right away:
void CanvasWidget::paint(QCPainter *p) { const float size = std::min(width(), height()); const QPointF center(width() / 2, height() / 2); // Paint the background circle QCRadialGradient gradient1(center.x(), center.y() - size*0.1, size*0.6); gradient1.setStartColor("#909090"); gradient1.setEndColor("#404040"); p->beginPath(); p->circle(center, size*0.46); p->setFillStyle(gradient1); p->fill(); p->setStrokeStyle("#202020"); p->setLineWidth(size*0.02); p->stroke();
See QCPainter, QCBrush, QCRadialGradient, QCImagePattern, QCImage, and QFont for more information on the features used by this example.
The image is used as a pattern, for filling the heart shape:
// Paint heart QCImagePattern pattern(m_image, center.x(), center.y(), size * 0.08, size * 0.05); p->setFillStyle(pattern);
When resources like QCImage and QCOffscreenCanvas are involved, these are managed in initializeResources() and graphicsResourcesInvalidated():
void CanvasWidget::initializeResources(QCPainter *p) { Q_ASSERT(m_image.isNull()); const auto flags = QCPainter::ImageFlag::Repeat | QCPainter::ImageFlag::GenerateMipmaps; m_image = p->addImage(QImage(":/qt-translucent.png"), flags); } void CanvasWidget::graphicsResourcesInvalidated() { m_image = {}; }
initializeResources() is merely a convenience. Instead of implementing it, one could also write the following in paint():
if (m_image.isNull()) m_image = p->addImage(QImage(":/qt-translucent.png"), QCPainter::ImageFlag::Repeat);
This example does not reparent widgets between windows, so graphics resources are not going to be lost. It is nonetheless a good pattern to assign a default, empty object to all QCImage and QCOffscreenCanvas variables in graphicsResourcesInvalidated().
The main() function creates a QMainWindow and QMdiArea. Multiple instances of the CanvasWidget class can be added as sub-windows. Due to hasSharedPainter() defaulting to true, and due to being placed within the same top-level widget, all the painter widgets will share the same QCPainter and the associated rendering infrastructure, instead of creating dedicated ones.
© 2025 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.