- Qt 6.12
- Qt Canvas Painter
- C++ Classes
- QCanvasPainterWidget
- Qt Canvas Painter | Commercial or GPLv3

# QCanvasPainterWidget Class

QCanvasPainterWidget is a widget for rendering using QCanvasPainter. More...

Header: | `#include <QCanvasPainterWidget>`
CMake: | `find_package(Qt6 REQUIRED COMPONENTS CanvasPainter)` `target_link_libraries(mytarget PRIVATE Qt6::CanvasPainter)`
Since: | Qt 6.11
Inherits: | QRhiWidget

- List of all members, including inherited members

## Public Functions

| QCanvasPainterWidget(QWidget *parent = nullptr)
virtual | ~QCanvasPainterWidget() override
QColor | fillColor() const
void | grabCanvas(const QCanvasOffscreenCanvas &canvas, const QObject *context, Functor &&callback)
bool | hasSharedPainter() const
void | setFillColor(const QColor &color)
void | setSharedPainter(bool enable)

## Protected Functions

void | beginCanvasPainting(QCanvasOffscreenCanvas &canvas)
void | endCanvasPainting()
virtual void | graphicsResourcesInvalidated()
virtual void | initializeResources(QCanvasPainter *painter)
virtual void | paint(QCanvasPainter *painter)
virtual void | prePaint(QCanvasPainter *painter)

## Reimplemented Protected Functions

virtual void | initialize(QRhiCommandBuffer *cb) override
virtual void | releaseResources() override
virtual void | render(QRhiCommandBuffer *cb) override

## Detailed Description

Implement the paint virtual function in a subclass to perform rendering using a QCanvasPainter.

The below code snippet shows the typical structure of a QCanvasPainterWidget subclass:

     class MyWidget : public QCanvasPainterWidget
     {
     public:
         void initializeResources(QCanvasPainter *p) override
         {
             // load assets
             if (m_image.isNull())
                 m_image = p->addImage(QImage("image.png"), QCanvasPainter::ImageFlag::Repeat);
         }

         void paint(QCanvasPainter *p) override
         {
             // ... draw using m_image
         }

         void graphicsResourcesInvalidated() override
         {
             // textures are lost, indicate the need for reload
             m_image = {};
         }

         QCanvasImage m_image;
     };

## Member Function Documentation

### `[explicit]` QCanvasPainterWidget::QCanvasPainterWidget(QWidget *parent = nullptr)

Constructs a QCanvasPainterWidget with the given parent.

### `[override virtual noexcept]` QCanvasPainterWidget::~QCanvasPainterWidget()

Destroys the QCanvasPainterWidget.

### `[protected]` void QCanvasPainterWidget::beginCanvasPainting(QCanvasOffscreenCanvas &canvas)

Starts recording QCanvasPainter draw commands targeting canvas.

Note: This function should only be called from prePaint().

beginCanvasPainting() must always be followed by corresponding endCanvasPainting() before returning from prePaint().

The following snippet from a QCanvasPainterWidget subclass shows how an offscreen canvas could be rendered into and then used as an image or image pattern when drawing the contents for the widget:

     class MyWidget : public QCanvasPainterWidget
     {
     public:
         QCanvasOffscreenCanvas canvas;
         QCanvasImage canvasImage;

         void graphicsResourcesInvalidated() override
         {
             canvas = {}; // so that the next prePaint() will recreate and redraw the canvas
         }

         void prePaint(QCanvasPainter *p) override
         {
             if (canvas.isNull()) {
                 canvas = p->createCanvas(QSize(320, 240));
                 beginCanvasPainting(canvas);
                 p->beginPath();
                 p->circle(160, 120, 20);
                 p->setFillStyle(Qt::red);
                 p->fill();
                 endCanvasPainting();
                 canvasImage = p->addImage(canvas, QCanvasPainter::ImageFlag::Repeat);
             }
         }

         void paint(QCanvasPainter *p) override
         {
             // use canvasImage as a brush or with drawImage()
         }
     };

### `[protected]` void QCanvasPainterWidget::endCanvasPainting()

Indicates the end of the drawing targeting the canvas specified in beginCanvasPainting().

Note: This function should only be called from prePaint().

beginCanvasPainting() must always be followed by corresponding endCanvasPainting() before returning from prePaint().

### QColor QCanvasPainterWidget::fillColor() const

Returns the current fill color.

See also setFillColor().

### template <typename Functor> void QCanvasPainterWidget::grabCanvas(const QCanvasOffscreenCanvas &canvas, const QObject *context, Functor &&callback)

Issues a texture readback request for canvas, associating it with context.

callback is invoked on the current (main/gui) thread either before the function returns, or later, depending on the underlying QRhi and 3D API implementation. Reading back texture contents may involve a GPU->CPU copy, depending on the GPU architecture. It takes a single `const QImage &` argument, and can be any functor, including move-only ones.

If context is destroyed before the readback completes, the grab is cancelled and callback is not invoked. This makes it safe for the callback to reference objects that may not outlive the pending readback.

For example, the following would save the contents of an offscreen canvas to a PNG file:

     grabCanvas(m_offscreenCanvas, this, [](const QImage &image) {
         image.save("result.png");
     });

### `[virtual protected]` void QCanvasPainterWidget::graphicsResourcesInvalidated()

Called when underlying graphics resources, such as textures, are lost.

This indicates that QCanvasImage objects returned from addImage() are no longer valid, and addImage() needs to be called again. If the paint() implementation is such that this does not matter, for example because images are not used, or addImage() is always called, then no action is necessary. Otherwise, it is recommended to toggle a flag, or similar, and act accordingly in the next invocation of paint().

The same applies to QCanvasOffscreenCanvas objects returned from QCanvasPainter::createCanvas(). When this function is called, the next invocation of paint() should create new canvases and redraw their contents.

Graphics resources can be lost, for example, when the widget is moved to a new top-level window, because that implies being associated with a new QRhi instance.

See also QRhiWidget::releaseResources().

### bool QCanvasPainterWidget::hasSharedPainter() const

Returns `true` if this widget uses a shared painter.

See also setSharedPainter.

### `[override virtual protected]` void QCanvasPainterWidget::initialize(QRhiCommandBuffer *cb)

Reimplements: QRhiWidget::initialize(QRhiCommandBuffer *cb).

### `[virtual protected]` void QCanvasPainterWidget::initializeResources(QCanvasPainter *painter)

Reimplement this method to initialize resources using painter. Generally, this will be called once before the first prePaint() and paint(). An exception is when graphics resources are lost, see graphicsResourcesInvalidated(). In that case, this method will get invoked again afterwards.

The default implementation is empty.

### `[virtual protected]` void QCanvasPainterWidget::paint(QCanvasPainter *painter)

Reimplement this method to paint using painter.

The widget is first filled with fillColor().

The default implementation is empty.

### `[virtual protected]` void QCanvasPainterWidget::prePaint(QCanvasPainter *painter)

Reimplement this function to perform drawing into one or more offscreen canvases using painter.

The default implementation is empty.

See also beginCanvasPainting() and endCanvasPainting().

### `[override virtual protected]` void QCanvasPainterWidget::releaseResources()

Reimplements: QRhiWidget::releaseResources().

### `[override virtual protected]` void QCanvasPainterWidget::render(QRhiCommandBuffer *cb)

Reimplements: QRhiWidget::render(QRhiCommandBuffer *cb).

### void QCanvasPainterWidget::setFillColor(const QColor &color)

Set the fill color to color. This color will be used to draw the background of the item. The default color is black.

See also fillColor().

### void QCanvasPainterWidget::setSharedPainter(bool enable)

Disable painter sharing if enable is `false`.

If painter sharing is enabled, all QCanvasPainterWidget instances inside the same QWindow will use the same QCanvasPainter. This function must be early, e.g. from the derived class' constructor, and must not be changed afterwards.

Painter sharing is enabled by default.

If two widgets use dedicated, non-shared painters, each other's graphics resources, such as the ones backing QCanvasImage or QOffscreenCanvas, will not be visible to them. Whereas if the widgets are in the same window, and sharing is enabled, they can use images or canvases created by the other widget, because they both use the same QCanvasPainter.

Note: Even when enable is true, painters are not shared between widgets belonging to different windows (top-level widgets).

See also hasSharedPainter.