Qt Canvas Painter – Beispielgalerie

Veranschaulicht die Funktionen von „ QCanvasPainter “ in einer „ Qt Quick “-Anwendung.

Galerie mit Pinseln unter dem Titel „Farbverläufe und Bildmuster“, die ein Raster aus Farbverlaufsfeldern und gemusterten Kacheln zeigt

Das Galerie-Beispiel ist eine „ Qt Quick “-Anwendung, die eine Vielzahl der von „ QCanvasPainter “ angebotenen Funktionen vorstellt.

Die Benutzeroberfläche besteht im Wesentlichen aus einem „ ListView “, wobei der Delegat „ GalleryItem “ ist – ein in C++ implementierter Typ, der für QML verfügbar ist.

class GalleryItem : public QCanvasPainterItem
{
    Q_OBJECT
    QML_NAMED_ELEMENT(GalleryItem)
    Q_PROPERTY(int galleryView READ galleryView WRITE setGalleryView NOTIFY galleryViewChanged)
    Q_PROPERTY(float animationTime READ animationTime WRITE setAnimationTime NOTIFY animationTimeChanged)
    Q_PROPERTY(float animationSine READ animationSine WRITE setAnimationSine NOTIFY animationSineChanged)
    Q_PROPERTY(float animState READ animState WRITE setAnimState NOTIFY animStateChanged)

Mit Qt 5 und OpenGL hätte „GalleryItem“ eine Unterklasse von „ QQuickPaintedItem “ sein können. Mit Qt 6 und „Canvas Painter“ werden wir eine Unterklasse von „ QCanvasPainterItem “ erstellen, die beschleunigtes Rendering über „ QCanvasPainter “ bereitstellt, anstatt das einfache Software-Rendering von „ QQuickPaintedItem “ und „QPainter“ zu verwenden.

Die Implementierung von `GalleryItem` ist einfach. Durch die Neuimplementierung der virtuellen Funktion ` createItemRenderer()` erstellen wir eine Instanz von `GalleryItemRenderer`, die eine Unterklasse von ` QCanvasPainterItemRenderer` darstellt.

GalleryItem::GalleryItem(QQuickItem *parent)
:  QCanvasPainterItem(parent)
{
}

QCanvasPainterItemRenderer* GalleryItem::createItemRenderer() const
{
    return new GalleryItemRenderer();
}

Das eigentliche Zeichnen wird in dieser Klasse implementiert:

class GalleryItemRenderer : public QCanvasPainterItemRenderer
{
public:
    explicit GalleryItemRenderer();
    ~GalleryItemRenderer();

    void initializeResources(QCanvasPainter *painter) override;
    void synchronizeData(QCanvasPainterItem *item) override;
    void paint(QCanvasPainter *painter) override;

initializeResources() registriert Bilder, die über QImage geladen wurden, sowie Shader für die benutzerdefinierten Pinsel.

void GalleryItemRenderer::initializeResources(QCanvasPainter *painter)
{
    QCanvasPainter::ImageFlags flags = QCanvasPainter::ImageFlag::Repeat | QCanvasPainter::ImageFlag::GenerateMipmaps;
    m_patternImage = painter->addImage(QImage(":/images/pattern1.png"), flags);
    m_patternImage2 = painter->addImage(QImage(":/images/pattern2.png"), flags);
    m_patternImage3 = painter->addImage(QImage(":/images/pattern3.png"), flags);
    m_testImage = painter->addImage(QImage(":/images/qt_development_white.png"));
    m_gradientImage1 = painter->addImage(QImage(":/images/gradient1.png"));
    m_gradientImage2 = painter->addImage(QImage(":/images/gradient2.png"));
    m_gradientImage3 = painter->addImage(QImage(":/images/gradient3.png"));
    image3Gray = painter->addImage(QImage(":/images/face-smile-bw.png"));
    image3Plain = painter->addImage(QImage(":/images/pattern2.png"));
    image3Nearest = painter->addImage(QImage(":/images/pattern2.png"),
                                        QCanvasPainter::ImageFlag::Nearest);
    image3Mips = painter->addImage(QImage(":/images/pattern2.png"),
                                     QCanvasPainter::ImageFlag::GenerateMipmaps);
    image3NearestMips = painter->addImage(QImage(":/images/pattern2.png"),
                                            QCanvasPainter::ImageFlag::Nearest | QCanvasPainter::ImageFlag::GenerateMipmaps);
    m_customBrush.setFragmentShader(":/qcgalleryexample/brush1.frag.qsb");
    m_customBrush2.setFragmentShader(":/qcgalleryexample/brush2.frag.qsb");
    m_customBrush3.setFragmentShader(":/qcgalleryexample/brush3.frag.qsb");
    m_customBrush3.setVertexShader(":/qcgalleryexample/brush3.vert.qsb");
    m_customBrush4.setFragmentShader(":/qcgalleryexample/brush4.frag.qsb");
    // Enable iTime animations
    m_customBrush.setAnimationRunning(true);
    m_customBrush2.setAnimationRunning(true);
    m_customBrush3.setAnimationRunning(true);
    m_customBrush4.setAnimationRunning(true);
}

`synchronizeData()` übernimmt das Kopieren der `GalleryItem`-Daten, damit später im Render-Thread des `Qt Quick `-Szenengraphen sicher darauf zugegriffen werden kann:

void GalleryItemRenderer::synchronizeData(QCanvasPainterItem *item)
{
    // Setting values here synchronized
    GalleryItem *realItem = static_cast<GalleryItem*>(item);
    if (realItem) {
        m_animationTime = realItem->animationTime();
        m_animationSine = realItem->animationSine();
        m_animState = realItem->animState();
        m_viewIndex = realItem->galleryView();
        if (!qFuzzyCompare(m_previousWidth, width()) ||
            !qFuzzyCompare(m_previousHeight, height())) {
            m_sizeChanged = true;
            m_previousWidth = width();
            m_previousHeight = height();
        } else {
            m_sizeChanged = false;
        }
        loadTigerPath();
    }

}

Die Implementierung von `paint()` führt das Rendern mithilfe von ` QCanvasPainter` durch, abhängig vom aktuellen Index, der von ` ListView` bereitgestellt wird:

void GalleryItemRenderer::paint(QCanvasPainter *painter)
{
    Q_UNUSED(painter)

    // Views not currently centered to have reduced
    // alpha and saturation.
    m_viewAlpha = 0.2 + 0.8 * m_animState;
    m_viewSaturation = m_animState;
    painter->setGlobalAlpha(m_viewAlpha);
    painter->setGlobalSaturation(m_viewSaturation);
    m_topMargin = height() * 0.02f;
    switch (m_viewIndex) {
    case 0:
        drawRectsWithLinearGradient();
        drawRectsWithRadialGradient();
        drawRectsWithBoxGradient();
        drawRectsWithConicalGradients();
        drawRectsWithImagePattern();
        drawRectsWithBrushStroke();
        break;
    case 1:
        drawImages();
        break;
    case 2:
        drawGridPatterns();
        break;

Die von hier aus aufgerufenen Funktionen nutzen die QCanvasPainter -API, um das Rendern durchzuführen. Zum Beispiel:

void GalleryItemRenderer::drawRectsWithBrushStroke()
{
    int rects = 3;
    float margin = width()*0.02f;
    float border = margin + margin * m_animationSine;
    float w = (width() - margin) / (rects+2) - margin;
    float w2 = w - border;
    float posX = w + 2 * margin + border/2;
    float posY = m_topMargin + 5*(w+margin) + border/2;

    QRectF rect1(posX,posY,w2,w2);
    painter()->setLineWidth(border);
    painter()->setFillStyle(QCanvasImagePattern(m_patternImage3));
    QCanvasLinearGradient g1(posX, posY, posX+w2, posY+w2);
    g1.setStartColor("#ffffff");
    g1.setEndColor("#000000");
    painter()->setStrokeStyle(g1);
    painter()->beginPath();
    painter()->roundRect(rect1, border);
    painter()->fill();
    painter()->stroke();
    posX += w + margin;

Weitere Details finden Sie im vollständigen Beispielquellcode, der unten verlinkt ist.

Beispielprojekt @ 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.