Qt Canvas Painter - 갤러리 예제
Qt Quick 애플리케이션에서 QCanvasPainter 의 기능을 보여줍니다.

갤러리 예제는 QCanvasPainter 가 제공하는 다양한 기능을 보여주는 Qt Quick 애플리케이션입니다.
사용자 인터페이스는 본질적으로 ListView 이며, 여기서 델리게이트는 C++로 구현되어 QML에 노출된 GalleryItem 입니다.
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)Qt 5와 OpenGL을 사용했다면 GalleryItem은 QQuickPaintedItem 의 서브클래스가 될 수 있었을 것입니다. Qt 6과 Canvas Painter를 사용함에 따라, 우리는 QQuickPaintedItem 및 QPainter의 일반 소프트웨어 렌더링을 사용하는 대신 QCanvasPainter 을 통해 가속화된 렌더링을 제공하는 QCanvasPainterItem 을 상속받은 서브클래스를 만들 것입니다.
GalleryItem의 구현은 간단합니다. 가상 함수 createItemRenderer()을 재구현하여, QCanvasPainterItemRenderer 의 서브클래스인 GalleryItemRenderer의 인스턴스를 생성합니다.
GalleryItem::GalleryItem(QQuickItem *parent)
: QCanvasPainterItem(parent)
{
}
QCanvasPainterItemRenderer* GalleryItem::createItemRenderer() const
{
return new GalleryItemRenderer();
}실제 그리기 처리는 이 클래스에서 구현됩니다:
class GalleryItemRenderer : public QCanvasPainterItemRenderer
{
public:
explicit GalleryItemRenderer();
~GalleryItemRenderer();
void initializeResources(QCanvasPainter *painter) override;
void synchronizeData(QCanvasPainterItem *item) override;
void paint(QCanvasPainter *painter) override;initializeResources()는 QImage 를 통해 로드된 이미지와 사용자 정의 브러시용 셰이더를 등록합니다.
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()는 나중에 Qt Quick 장면 그래프의 렌더링 스레드에서 안전하게 액세스할 수 있도록 GalleryItem 데이터를 복사하는 역할을 합니다:
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();
}
}paint() 구현은 ListView 에서 제공하는 현재 인덱스에 따라 QCanvasPainter 를 사용하여 렌더링합니다:
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;여기서 호출되는 함수들은 QCanvasPainter API를 사용하여 렌더링을 수행합니다. 예를 들어:
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;자세한 내용은 아래 링크된 전체 예제 소스 코드를 확인하세요.
© 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.