Home

Awesome

QNanoPainter

QNanoPainter is an OpenGL accelerated C++ vector drawing library for Qt, offering optimal performance, productivity and rendering quality all-in-one. QNanoPainter API is a mixture of QPainter and HTML5 canvas APIs. In other words, it's very close to HTML5 canvas but transformed to object oriented C++ with separate classes.

QNanoPainter can be used together with Qt5 UIs in different ways:

QNanoPainter uses excellent NanoVG as its rendering backend.

Screenshots

<img src="doc/images/sc_qnanopainter_1.png" width="24%"><img src="doc/images/sc_qnanopainter_2.png" width="24%"><img src="doc/images/sc_events_1.png" width="24%"><img src="doc/images/sc_helloworld_1.png" width="24%"> <img src="doc/images/sc_gallery_1.png" width="24%"><img src="doc/images/sc_gallery_2.png" width="24%"><img src="doc/images/sc_gallery_3.png" width="24%"><img src="doc/images/sc_gallery_4.png" width="24%">

Features

Here is a non exhaustive list of QNanoPainter features:

Usage

Taking QNanoPainter into use in your Qt application is simple:

include(src/libqnanopainter/include.pri)

For custom QQuickItem

qmlRegisterType<MyQNanoItem>("MyQNanoItem", 1, 0, "MyQNanoItem");
import QtQuick 2.4
import MyQNanoItem 1.0

Item {
	...
	MyQNanoItem {
		anchors.fill: parent
	}
}

To create own QNanoPainter item you should implement 2 classes:

The main reason for two classes is that these will run in separate threads for optimal performance. And because of this, all communication between these two need to happen in synchronize() method.

Here is a complete HelloWorld example item:

#include "qnanoquickitem.h"
#include "qnanoquickitempainter.h"

// HelloItemPainter contains the painting code
class HelloItemPainter : public QNanoQuickItemPainter
{
    Q_OBJECT

public:
    HelloItemPainter()
    {
    }

    void paint(QNanoPainter *p)
    {
        // Paint the background circle
        p->beginPath();
        p->circle(width()*0.5, height()*0.5, width()*0.46);
        QNanoRadialGradient gradient1(width()*0.5, height()*0.4, width()*0.6, width()*0.2);
        gradient1.setStartColor("#808080");
        gradient1.setEndColor("#404040");
        p->setFillStyle(gradient1);
        p->fill();
        p->setStrokeStyle("#202020");
        p->setLineWidth(width()*0.02);
        p->stroke();
        // Hello text
        p->setTextAlign(QNanoPainter::ALIGN_CENTER);
        p->setTextBaseline(QNanoPainter::BASELINE_MIDDLE);
        QNanoFont font1(QNanoFont::DEFAULT_FONT_BOLD_ITALIC);
        font1.setPixelSize(width()*0.08);
        p->setFont(font1);
        p->setFillStyle("#B0D040");
        p->fillText("HELLO", width()*0.5, height()*0.4);
        // QNanoPainter text
        QNanoFont font2(QNanoFont::DEFAULT_FONT_THIN);
        font2.setPixelSize(width()*0.18);
        p->setFont(font2);
        p->fillText("QNanoPainter", width()*0.5, height()*0.5);
    }
};

// HelloItem provides the API towards QML
class HelloItem : public QNanoQuickItem
{
    Q_OBJECT

public:
    HelloItem(QQuickItem *parent = 0)
        :  QNanoQuickItem(parent)
    {
    }

    // Reimplement
    QNanoQuickItemPainter *createItemPainter() const
    {
        // Create painter for this item
        return new HelloItemPainter();
    }
};

For custom QWidget or QWindow

Implement your own QNanoWidget or QNanoWindow subclass depending on your needs. APIs of these are very similar, basically you just override paint() method like this:

#include "qnanowindow.h"
#include "qnanopainter.h"

class HelloWindow : public QNanoWindow
{
public:
    HelloWindow()
    {
        setFillColor("#ffffff");
    }

    void paint(QNanoPainter *p)
    {
        // Paint using QNanoPainter here
        ...
    }
};

Example how to render QImage

QNanoPainter can render QImage. The principle is that on the first render pass the QImage is loaded and put into cache and on the second pass it will be used from the cache.

QImage is automatically converted to the correct pixel format (Format_RGBA8888_Premultiplied).

Here's how to do it in paint function:

    QImage loadImage(const QString &fileName)
    {
        // Load and return QImage
        return QImage();
    }

    void paint(QNanoPainter *painter)
    {
        QString imageFileName; // Path to your image file

        QNanoImage nanoImage = QNanoImage::fromCache(painter, imageFileName);
        QSize imageSize(nanoImage.width(), nanoImage.height());
        if (imageSize.isEmpty()) {
            QImage image(loadImage(imageFileName));
            if (image.isNull())
                return;

            nanoImage = QNanoImage(image, imageFileName);
            imageSize = image.size();
        }

        // Render QNanoImage using painter
    }

API Reference

Sources contain API documentation written with QDoc. To generate the documentation:

> cd doc
> [Qt bin path]/qdoc qnanopainter.qdocconf 

Documentation is work-in-progress, patches welcome =)

License

The library is licensed under zlib license.

Links