Qt Quick2 Creating qmlRegisterSingletonType for Singleton Class Type

Viewed 872

I am trying to create a singleton property using qmlRegisterSingletonType but when I try to access the object in the QML I am getting below error in the console logs:

qrc:/qml/MyQml.qml:21 Element is not creatable.

Below is my code:

// TestSingletonType.h Class

#include <QObject>
#include <QJsonObject>
#include <QVariantMap>
#include <QQmlEngine>

class TestSingletonType : public QObject
{
    Q_OBJECT
    Q_DISABLE_COPY(TestSingletonType)
    TestSingletonType(QObject *parent = nullptr) {}

public: 

    // To maintain single object of the class
    static QObject *qmlInstance(QQmlEngine *engine, QJSEngine *scriptEngine)
    {
        Q_UNUSED(engine);
        Q_UNUSED(scriptEngine);

        if (theInstance == NULL)
            theInstance = new TestSingletonType();

        return theInstance;
    }

private:

    static QObject *theInstance; // I have set it to NULL in Cpp file
};

// Main.cpp

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;

    qmlRegisterSingletonType<TestSingletonType>("com.my.TestSingletonType", 1, 0, "TestSingletonType", &TestSingletonType::qmlInstance);

    // Rest of the code to load the QML

    return app.exec();
} 

// MyQml.qml file:

import QtQuick 2.0
import QtQuick.Controls 2.0
import com.my.TestSingletonType 1.0

Item {

    TestSingletonType {      <---- Getting error on this line 
        id: mySingleClass
    }

    // Rest of my code which uses "mySingleClass"
}

If I use qmlRegisterType then it works properly, but not with the qmlRegisterSingletonType.

I have referred the below answer and link:
How to implement a singleton provider for qmlRegisterSingletonType?
https://doc.qt.io/qt-5/qqmlengine.html#qmlRegisterSingletonType

1 Answers

The error is clear: A singleton is not created in QML since it was already created in the callback (qmlInstance method), you just have to access the properties of that method. The typeName ("TestSingletonType") is the id.

Item {
    // binding property
    foo_property : TestSingletonType.foo_value 
    // update singleton property
    onAnotherPropertyChanged: TestSingletonType.another_prop = anotherProperty
}

// listen singleton signal
Connections{
    target: TestSingletonType
    onBarChanged: bar_object.bar_property = bar
}
Related