Search code examples
c++qtqmlqt5qpainterpath

QML : What is the equivalent of QPainterPath?


In order to convert one GUI interface written in C++ with the Qt libraries to QML, I've to find an alternative to QPainterPath in QML. Indeed, for now, a bunch of shapes are drawn in the GUI interface and the C++ code modifies the color of those objects when certain events happen. QPainterPath objects are used to store those shapes.

I would appreciate if you can show me how to draw two rectangle objects in a QML canvas and then how to modify their filled color within the C++ code.


Solution

  • As I said in my comment, one option could be Canvas, it has methods similar to QPainterPath. In the next part I will show an example where the color can be changed from C ++ through a method that generates random colors and are called by a QTimer:

    main.cpp

    #include <QColor>
    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlContext>
    #include <QTime>
    #include <QTimer>
    
    class ColorProvider: public QObject{
        Q_OBJECT
        Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
    public:
    
        QColor color() const{
            return mColor;
        }
        void setColor(const QColor &color){
            if(color == mColor)
                return;
            mColor = color;
            emit colorChanged(mColor);
        }
    
        Q_INVOKABLE void randomColor(){
            qsrand((uint)QTime::currentTime().msec());
            setColor(QColor(qrand() % 256, qrand() % 256, qrand() % 256));
        }
    
    signals:
        void colorChanged(const QColor &color);
    private:
        QColor mColor;
    };
    
    #include "main.moc"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        QGuiApplication app(argc, argv);
    
        ColorProvider obj;
    
        QTimer timer;
        QObject::connect(&timer, &QTimer::timeout, &obj, &ColorProvider::randomColor);
        timer.start(100);
    
        QQmlApplicationEngine engine;
        engine.rootContext()->setContextProperty("colorProvider", &obj);
        engine.load(QUrl(QLatin1String("qrc:/main.qml")));
        if (engine.rootObjects().isEmpty())
            return -1;
    
        return app.exec();
    }
    

    main.qml

    import QtQuick 2.7
    import QtQuick.Controls 2.0
    
    ApplicationWindow {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        Canvas {
            id:canvas
            anchors.fill: parent
            onPaint:{
                var ctx = canvas.getContext('2d');
                ctx.lineWidth = 4
                ctx.fillStyle = "orange"
                ctx.strokeStyle = "red"
                ctx.fillRect(50, 40, 100, 100)
                ctx.stroke()
                ctx.fill()
    
                ctx.lineWidth = 10
                ctx.fillStyle = colorProvider.color
                ctx.fillRect(150, 150, 300, 300)
                ctx.stroke()
                ctx.fill()
    
                ctx.roundedRect(20, 20, 40, 40, 10, 10)
            }
        }
    
        Connections {
            target: colorProvider
            onColorChanged: canvas.requestPaint()
        }
    }
    

    The complete example can be found in the following link.