Thursday, May 12, 2016

Qt C++ to Qml Communication using qmlRegisterUncreatableType()


In this article i will discuss about how to access the C++ class  enum types and attributes in qml file using Qt c++ qmlRegisterUncreatableType() template function.

qmlRegisterUncreatableType() will register the c++ class type (derived from QObject) as the non-instantiable type with QML type system. So we can not create object for the class in qml file, but we can use the properties ans enumerated types belongs to this class in qml file.

To access the enum values in qml , we have to make it available to meta-object system with the following macro, Otherwise we cannot access in qml file.
Q_ENUMS(enumType)

To Register the c++ type with qml type system
 qmlRegisterUncreatableType("ModuleName/uri", MajorVersion, MinorVersion, "QmlName", "message");

Here i'm providing the sample code to demonstrate the use of qmlRegisterUncreatableType() to access c++ class attributes and enum types.

Note: C++ class must be QObject derived to register with qml type system

>main.cpp
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QtQml>

#include "mycppclass.h"
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    MyCPPClass myCppObj;
    qmlRegisterUncreatableType<MyCPPClass>("MyModule",1,0,"MyCPPClass","can not instantiate MyCPPClass in qml");

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("myCppObj",&myCppObj);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

>MyCPPClass.h

#include <QObject>
#include <QString>
#include<QColor>

class MyCPPClass : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QColor mycolour READ mycolour WRITE setMycolour NOTIFY mycolourChanged)
    Q_PROPERTY(int num READ num WRITE setNum NOTIFY numChanged)

    Q_ENUMS(NumbersType)

public:
    explicit MyCPPClass(QObject *parent = 0);

    QColor mycolour();
    void setMycolour(QColor clr);

    int num();
    void setNum(int n);

    Q_INVOKABLE QString getClassName();

    enum NumbersType {
        ONE = 1,
        TWO = 2,
        THREE = 3,
        FOUR= 4,
        FIVE = 5,
        SIX = 6,
        SEVEN =7 ,
        EIGHT = 8,
        Nine = 9
    };

signals:
    void mycolourChanged();
    void numChanged();

public slots:

private:
    QColor m_colour;
    int m_num;
};
Note:To access enum types in qml file we have to start enum values with Capital letter. Ex: Nine = 9

>MyCPPClass.cpp
#include "mycppclass.h"

MyCPPClass::MyCPPClass(QObject *parent) : QObject(parent)
{
}

QColor MyCPPClass::mycolour()
{
    return m_colour;
}

void MyCPPClass::setMycolour(QColor clr)
{
    m_colour = clr;
    Q_EMIT mycolourChanged();
}

int MyCPPClass::num()
{
    return m_num;
}

void MyCPPClass::setNum(int n)
{
    m_num = n;
    Q_EMIT numChanged();
}

QString MyCPPClass::getClassName()
{
    return "MyCPPClass";
}

and finally
>main.qml 
import QtQuick 2.4
import MyModule 1.0 
Rectangle {
        Component.onCompleted: {
            myCppObj.mycolour = "red"
            myCppObj.num = 300;
        }
        height: myCppObj.num
        width: myCppObj.num
        color: myCppObj.mycolour

        Text {
            id: name
            text: qsTr("This is from C++ class:\t"+myCppObj.getClassName()+" \n enum value: "+MyCPPClass.EIGHT)
        }
    }
 Output:

No comments:

Post a Comment