Registering a Singleton object to use “Static” methods in QML

Info Thread
By -
0

 

The notion of static methods that are used in QML differs somewhat from the classical one in C ++, when static methods are created in the class that can be used referring to the class name, rather than to a specific object. In the case of QML, things are somewhat different. In order to use such methods in QML, which are present in the C ++ class, it is necessary to register a Singleton object that will provide the required methods, and these methods should no longer be static in themselves. They should at least be labeled with the Q_INVOKABLE macro so that they can be used in QML.

To register Singleton , you need to use the qmlRegisterSingletonType function, which in addition to the standard parameters that are passed to qmlRegisterType, you must also pass the static singletonProvider function, which you also write yourself.


Project structure

Create a Qt Quick project that will contain the following files:

  • SingletonQMLCpp.pro – Project profile
  • main.cpp – File with main function
  • main.qml – Main qml file
  • singletonclass.h – Singleton header file
  • singletonclass.cpp – Singleton source file

The project profile will be created by default and will not be changed.

main.cpp

Let’s start with the file main.cpp, in which we will register the object of the future singleton.

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtQml> // We connect to use qmlRegisterSingletonType
 
#include "singletonclass.h" // We connect the header file SingletonClass
 
int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
 
    // Register the singleton object through the function singletonProvider, that is, we pass the pointer to it as an argument.
    qmlRegisterSingletonType<SingletonClass>("SingletonClass", 1, 0, "SingletonClass", singletonProvider);
 
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;
 
    return app.exec();
}

singletonclass.h

In the header file, define enum, which we will use to get certain messages through the “static” getMessage method in the QML layer. In the same file, we define the static function singletonProvider , which will create a singleton instance.

#ifndef SINGLETONCLASS_H
#define SINGLETONCLASS_H
 
#include <QObject>
#include <QQmlEngine>
#include <QJSEngine>
 
class SingletonClass : public QObject
{
    Q_OBJECT
public:
    explicit SingletonClass(QObject *parent = nullptr);
 
    enum class Message {
        Info,
        Debug,
        Warning,
        Error
    };
    // Enum registration for use in QML
    Q_ENUM(Message)
 
    // To use this method in QML, declare it in Q_INVOKABLE
    Q_INVOKABLE QString getMessage(Message message);
 
signals:
 
public slots:
};
 
static QObject *singletonProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
{
    Q_UNUSED(engine)
    Q_UNUSED(scriptEngine)
 
    SingletonClass *singletonClass = new SingletonClass();
    return singletonClass;
}
 
#endif // SINGLETONCLASS_H

Note that getMessage does not have to be static to act as a static Type method in QML.

singletonclass.cpp

This file provides the implementation of the getMessage method.

#include "singletonclass.h"
 
SingletonClass::SingletonClass(QObject *parent) : QObject(parent)
{
 
}
 
QString SingletonClass::getMessage(SingletonClass::Message message)
{
    switch (message)
    {
        case Message::Info:
            return "This is Info Message";
        case Message::Debug:
            return "This is Debug Message";
        case Message::Warning:
            return "This is Warning Message";
        case Message::Error:
            return "This is Error Message";
        default:
            return "Nothin not found";
    }
}

main.qml

And now let’s use this singleton type in QML.

import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
 
import SingletonClass 1.0 // Connect Singleton
 
 
Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Singleton Class")
 
    ListView {
        anchors.fill: parent
        delegate: Item {
            height: 48
            width: parent.width
            Text {
                anchors.fill: parent
                text: model.text
 
                verticalAlignment: Text.AlignVCenter
                horizontalAlignment: Text.AlignHCenter
            }
        }
 
        model: listModel
    }
 
    ListModel {
        id: listModel
 
        // There is no way to use methods and functions directly for property in ListElement, so this hack is used
        Component.onCompleted: {
            listModel.append({'text': SingletonClass.getMessage(SingletonClass.Info)})
            listModel.append({'text': SingletonClass.getMessage(SingletonClass.Debug)})
            listModel.append({'text': SingletonClass.getMessage(SingletonClass.Warning)})
            listModel.append({'text': SingletonClass.getMessage(SingletonClass.Error)})
        }
    }
}

Conclusion

As a result, an application will be received that will display four messages in its window.

Thus, through the singleton object in QML, the ability to use cpp methods as static is added.

Download archive with project

Tags:

Post a Comment

0Comments

Post a Comment (0)