How to Register your C++ Class as a QML Type

Info Thread
By -
0

 

How to Register your C++ Class as a QML Type :

The second possibility to use C++ components in QML is to register the class as a QML type. This allows to create objects (= instances) of your type directly in QML instead of C++. And the best thing is, the concepts with signals, slots and properties we used in the previous example still apply.

When to Use a Context Property and when a QML Object

If there’s only a single object instance you want to work with in QML you can add the object as a context property. When there can be multiple instances of your class, register it as a QML type and create the objects directly in QML where you need it.

1. For this example, we will create a new type we can use in QML. Let’s start with adding a new C++ Class named SignalClass.

2. Replace the code in signalclass.h with this implementation:

#ifndef SIGNALCLASS_H
#define SIGNALCLASS_H

#include <QObject>

class SignalClass : public QObject
{
    Q_OBJECT
public:
    explicit SignalClass(QObject *parent = nullptr);
    Q_PROPERTY(int count READ count WRITE setCount NOTIFY countChanged)

    int count() const;
    void setCount(int newCount);

public slots:

signals:
    void countChanged();

private:
    int m_count{0}; //initialize the value
};

#endif // SIGNALCLASS_H

3. To complete the class, add the following code for signalclass.cpp:

#include "signalclass.h"

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

}

int SignalClass::count() const
{
    return m_count;
}

void SignalClass::setCount(int newCount)
{
    if (m_count == newCount)
        return;
    m_count = newCount;
    emit countChanged();
}

Register and Use your C++ QML Type

1. In your main.cpp, first add an include statement for the new class:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "signalclass.h"

int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    /*Register a class to available in QML*/
    qmlRegisterType<SignalClass>("SignalMechnism",1,0,"SignalClass");

    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

The method takes several parameters: The module identifier and version define the required QML import to use the type. The last parameter holds the name of the QML type, which can be different from the actual C++ class name.

3. Add the import which matches the used configuration of qmlRegisterType to your main.qml:

import SignalMechnism 1.0

4. For an example usage of our new QML Type, add the following snippet below the first example in main.qml file:

    SignalClass{
        id:signalMech
    }

Full main.qml file code

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.3
import QtQuick.Controls.Material 2.3
import SignalMechnism 1.0
ApplicationWindow {
    width: 640
    height: 480
    visible: true
    title: qsTr("Signal System Mechanism")
    SignalClass{
        id:signalMech
    }
    Label{
        id:mylabel
        text: qsTr("Current count is : ")+signalMech.count
        font.pixelSize: 24
        anchors.centerIn: parent
        color: "Green"
    }
    Button{
        text: qsTr("Count ++")
        highlighted: true
        anchors{
            top: mylabel.bottom
            topMargin: 20
            horizontalCenter: parent.horizontalCenter
        }

        onClicked: {
            signalMech.count = signalMech.count+1;
        }
    }
}
See the output
Note: You can find the whole source code on my github
Tags:

Post a Comment

0Comments

Post a Comment (0)