Evgenii Legotckoi
July 5, 2017, 4:05 p.m.

QML - Tutorial 029. Registering a Singleton object to use "Static" methods in QML

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.

  1. #include <QGuiApplication>
  2. #include <QQmlApplicationEngine>
  3. #include <QtQml> // We connect to use qmlRegisterSingletonType
  4.  
  5. #include "singletonclass.h" // We connect the header file SingletonClass
  6.  
  7. int main(int argc, char *argv[])
  8. {
  9. QGuiApplication app(argc, argv);
  10.  
  11.   // Register the singleton object through the function singletonProvider, that is, we pass the pointer to it as an argument.
  12. qmlRegisterSingletonType<SingletonClass>("SingletonClass", 1, 0, "SingletonClass", singletonProvider);
  13.  
  14. QQmlApplicationEngine engine;
  15. engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
  16. if (engine.rootObjects().isEmpty())
  17. return -1;
  18.  
  19. return app.exec();
  20. }

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.

  1. #ifndef SINGLETONCLASS_H
  2. #define SINGLETONCLASS_H
  3.  
  4. #include <QObject>
  5. #include <QQmlEngine>
  6. #include <QJSEngine>
  7.  
  8. class SingletonClass : public QObject
  9. {
  10. Q_OBJECT
  11. public:
  12. explicit SingletonClass(QObject *parent = nullptr);
  13.  
  14. enum class Message {
  15. Info,
  16. Debug,
  17. Warning,
  18. Error
  19. };
  20. // Enum registration for use in QML
  21. Q_ENUM(Message)
  22.  
  23. // To use this method in QML, declare it in Q_INVOKABLE
  24. Q_INVOKABLE QString getMessage(Message message);
  25.  
  26. signals:
  27.  
  28. public slots:
  29. };
  30.  
  31. static QObject *singletonProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
  32. {
  33. Q_UNUSED(engine)
  34. Q_UNUSED(scriptEngine)
  35.  
  36. SingletonClass *singletonClass = new SingletonClass();
  37. return singletonClass;
  38. }
  39.  
  40. #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.

  1. #include "singletonclass.h"
  2.  
  3. SingletonClass::SingletonClass(QObject *parent) : QObject(parent)
  4. {
  5.  
  6. }
  7.  
  8. QString SingletonClass::getMessage(SingletonClass::Message message)
  9. {
  10. switch (message)
  11. {
  12. case Message::Info:
  13. return "This is Info Message";
  14. case Message::Debug:
  15. return "This is Debug Message";
  16. case Message::Warning:
  17. return "This is Warning Message";
  18. case Message::Error:
  19. return "This is Error Message";
  20. default:
  21. return "Nothin not found";
  22. }
  23. }

main.qml

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

  1. import QtQuick 2.5
  2. import QtQuick.Window 2.2
  3. import QtQuick.Controls 1.4
  4.  
  5. import SingletonClass 1.0 // Connect Singleton
  6.  
  7.  
  8. Window {
  9. visible: true
  10. width: 640
  11. height: 480
  12. title: qsTr("Singleton Class")
  13.  
  14. ListView {
  15. anchors.fill: parent
  16. delegate: Item {
  17. height: 48
  18. width: parent.width
  19. Text {
  20. anchors.fill: parent
  21. text: model.text
  22.  
  23. verticalAlignment: Text.AlignVCenter
  24. horizontalAlignment: Text.AlignHCenter
  25. }
  26. }
  27.  
  28. model: listModel
  29. }
  30.  
  31. ListModel {
  32. id: listModel
  33.  
  34.   // There is no way to use methods and functions directly for property in ListElement, so this hack is used
  35. Component.onCompleted: {
  36. listModel.append({'text': SingletonClass.getMessage(SingletonClass.Info)})
  37. listModel.append({'text': SingletonClass.getMessage(SingletonClass.Debug)})
  38. listModel.append({'text': SingletonClass.getMessage(SingletonClass.Warning)})
  39. listModel.append({'text': SingletonClass.getMessage(SingletonClass.Error)})
  40. }
  41. }
  42. }

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

Do you like it? Share on social networks!

3
  • Oct. 2, 2018, 1:05 a.m.

In the debugger, I could not manage to see if the constructor is called once for all or if is called at every occurence from QML. Do you know?

Evgenii Legotckoi
  • Oct. 5, 2018, 6:11 p.m.

For QML constructor will be called once.

It works some differently from classic Singleton, but instance will be one.

Comments

Only authorized users can post comments.
Please, Log in or Sign up
  • Last comments
  • IscanderChe
    April 12, 2025, 5:12 p.m.
    Добрый день. Спасибо Вам за этот проект и отдельно за ответы на форуме, которые мне очень помогли в некоммерческих пет-проектах. Профессиональным программистом я так и не стал, но узнал мно…
  • AK
    April 1, 2025, 11:41 a.m.
    Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
  • Evgenii Legotckoi
    March 9, 2025, 9:02 p.m.
    К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
  • VP
    March 9, 2025, 4:14 p.m.
    Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
  • ИМ
    Nov. 22, 2024, 9:51 p.m.
    Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…