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

# QCanvasPainterItemRenderer Class

The QCanvasPainterItemRenderer handles all painting for a QCanvasPainterItem. More...

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

- List of all members, including inherited members

## Public Functions

| QCanvasPainterItemRenderer()
virtual | ~QCanvasPainterItemRenderer() override
QColor | fillColor() const
bool | hasSharedPainter() const
qreal | height() const
QCanvasPainter * | painter() const
void | setSharedPainter(bool enable)
qreal | width() const

## Protected Functions

void | beginCanvasPainting(QCanvasOffscreenCanvas &canvas)
void | endCanvasPainting()
void | grabCanvas(const QCanvasOffscreenCanvas &canvas, const QObject *context, Functor &&callback)
virtual void | initializeResources(QCanvasPainter *painter)
virtual void | paint(QCanvasPainter *painter)
virtual void | prePaint(QCanvasPainter *painter)
virtual void | synchronizeData(QCanvasPainterItem *item)

## Reimplemented Protected Functions

virtual void | initialize(QRhiCommandBuffer *cb) override
virtual void | render(QRhiCommandBuffer *cb) override
virtual void | synchronize(QQuickRhiItem *item) override

## Detailed Description

Implement the paint() method to perform the rendering.

To expose data from the item to the renderer in a thread-safe manner, implement synchronizeData().

The renderer object lives and operates on the Qt Quick scene graph render thread, if there is one, since that is the thread on which createItemRenderer() and all the functions in this class are invoked.

If the QCanvasPainterItem is moved to a different window, it will get associated with a new QRhi. Therefore, the renderer object is automatically destroyed, and a new one is created by invoking createItemRenderer() again. This allows simple management of QCanvasImage and QCanvasOffscreenCanvas objects, because they can be member variables in renderer, set up either in initializeResources() or in paint(), without having to reset them when the graphics resources are lost due to the window and QRhi change, since it all happens implicitly by the destruction of the whole renderer object.

The below code snippet shows the typical structure of a QCanvasPainterItemRenderer subclass. See QCanvasPainterItem for an example of the `MyItem` class.

     class MyRenderer : public QCanvasPainterItemRenderer
     {
     public:
         void synchronizeData(QCanvasPainterItem *item) override
         {
             // copy a custom property value from item in a thread-safe manner
             m_value = static_cast<MyItem *>(item)->value();
         }

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

         void prePaint(QCanvasPainter *p) override
         {
             // this is where offscreen canvases are drawn into
             if (m_canvas.isNull()) {
                 m_canvas = p->createCanvas(QSize(640, 480));
                 beginCanvasPainting(m_canvas);
                 // ... draw into the offscreen canvas
                 endCanvasPainting();
                 m_canvasImage = p->addImage(m_canvas);
             }
         }

         void paint(QCanvasPainter *p) override
         {
             QPointF center(width() / 2, height() / 2);
             // ... draw using m_value, m_image, and m_canvasImage
         }

         QCanvasImage m_image;
         QCanvasOffscreenCanvas m_canvas;
         QCanvasImage m_canvasImage;
         float m_value;
     };

See also QCanvasPainterItem.

## Member Function Documentation

### QCanvasPainterItemRenderer::QCanvasPainterItemRenderer()

Constructs a QCanvasPainterItemRenderer.

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

Destroys the QCanvasPainterItemRenderer.

### `[protected]` void QCanvasPainterItemRenderer::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().

### `[protected]` void QCanvasPainterItemRenderer::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 QCanvasPainterItemRenderer::fillColor() const

Return the current fill color of the item. This can be set by the parent QCanvasPainterItem.

### `[protected]` template <typename Functor> void QCanvasPainterItemRenderer::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 render 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(offscreenCanvas, item, [](const QImage &image) {
         image.save("result.png");
     });

### bool QCanvasPainterItemRenderer::hasSharedPainter() const

Returns `true` if this item renderer uses a shared painter.

See also setSharedPainter.

### qreal QCanvasPainterItemRenderer::height() const

Returns the height of the painted area, in logical units, without the scale factor (device pixel ratio). This is usually the same as the painter item's height, unless QQuickRhiItem::fixedColorBufferHeight has been set.

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

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

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

Reimplement this method to initialize resources using painter. This will be called once before the first synchronizeData().

Note: This function is not called when the size of the QCanvasPainterItem changes.

See also QCanvasPainter::addImage and QCanvasPainter::createCanvas.

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

Reimplement this method to paint using painter.

This will get called after the item has been filled with fillColor().

paint() is called from renderer thread. To access item data safely, copy it in synchronizeData().

See also synchronizeData().

### QCanvasPainter *QCanvasPainterItemRenderer::painter() const

Returns the painter attached to this painter item.

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

This function is called at the start of rendering using painter, before paint().

There is no render target active when this function is invoked. Call beginCanvasPainting() to initialize drawing into an offscreen canvas.

See also beginCanvasPainting() and endCanvasPainting().

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

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

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

Disable painter sharing if enable is `false`.

Painter sharing is enabled by default.

When painter sharing is enabled, all painter items inside the same QQuickWindow will use the same QCanvasPainter.

If disabling painter sharing is desired, this function must be called early enough, for example from the derived class' constructor. Changing it afterwards, when the item has already initialized for painting, will have no effect.

If two items 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 items are in the same window, and sharing is enabled, they can use images or canvases created by the other item, because they both use the same QCanvasPainter.

Note: Even when enable is true, painters are not shared between items belonging to different QQuickWindow instances, and by extension, to different scene graphs.

See also hasSharedPainter.

### `[override virtual protected]` void QCanvasPainterItemRenderer::synchronize(QQuickRhiItem *item)

Reimplements: QQuickRhiItemRenderer::synchronize(QQuickRhiItem *item).

### `[virtual protected]` void QCanvasPainterItemRenderer::synchronizeData(QCanvasPainterItem *item)

Reimplement this method to synchronize data between item and item painter instances. This will be called before paint() each time item needs to be repainted.

This method is the only place where it is safe for the painter and the item to read and write each others variables.

Usually you should static_cast item to your real item type, and then exchange the data.

### qreal QCanvasPainterItemRenderer::width() const

Returns the width of the painted area, in logical units, without the scale factor (device pixel ratio). This is usually the same as the painter item's width, unless QQuickRhiItem::fixedColorBufferWidth has been set.