Reference to Qml Singleton Class Instance?

I have created a class called LoginService. I registered it to QT QML file by using qmlRegisterSingletonType, now the problem is I can't get the loginservice instance which instantiated by QML. My current c++ code is:

static QObject *qmlInstance(QQmlEngine *engine, QJSEngine *scriptEngine) {
    Q_UNUSED(engine);
    Q_UNUSED(scriptEngine);

    LoginService::m_pThis = new LoginService;
    return m_pThis;
}

qmlRegisterSingletonType<LoginService>("com.test.LoginService", 1, 0, "LoginService", &LoginService::qmlInstance);
1

1 Answer

If you want to access the singleton from C++, create a method that returns an instance other than qmlInstance:

loginservice.h

#ifndef LOGINSERVICE_H
#define LOGINSERVICE_H

#include <QObject>

class QQmlEngine;
class QJSEngine;

class LoginService : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
public:
    static LoginService *instance();
    static QObject *qmlInstance(QQmlEngine *engine, QJSEngine *scriptEngine);

    QString name() const;
    void setName(const QString &name);
    Q_SIGNAL void nameChanged();

private:
    explicit LoginService(QObject *parent = nullptr);
    static LoginService* m_pThis;
    QString mName;
};

#endif // LOGINSERVICE_H

loginservice.cpp

#include "loginservice.h"

#include <QQmlEngine>

LoginService* LoginService::m_pThis = nullptr;
LoginService::LoginService(QObject *parent) : QObject(parent)
{

}

QString LoginService::name() const
{
    return mName;
}

void LoginService::setName(const QString &name)
{
    if(mName == name)
        return;
    mName = name;
    Q_EMIT nameChanged();
}

LoginService *LoginService::instance()
{
    if (m_pThis == nullptr) // avoid creation of new instances
        m_pThis = new LoginService;
    return m_pThis;
}

QObject *LoginService::qmlInstance(QQmlEngine *engine, QJSEngine *scriptEngine) {
    Q_UNUSED(engine);
    Q_UNUSED(scriptEngine);
    // C++ and QML instance they are the same instance
    return LoginService::instance();
}

main.cpp

#include "loginservice.h"

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QDebug>

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

    QGuiApplication app(argc, argv);

    qmlRegisterSingletonType<LoginService>("com.test.LoginService", 1, 0, "LoginService", &LoginService::qmlInstance);


    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    // get instance in C++
    LoginService *service = LoginService::instance();

    qDebug()<<service->name();
    return app.exec();
}

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2
import com.test.LoginService 1.0

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

   Component.onCompleted: LoginService.name = "testing"
}
4

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Alexander Ross

Alexander Ross

Gaming, Esports & Interactive Media Writer

Alexander Ross has covered the video game industry for a decade, writing deep dives on game design, esports tournaments, VR developments, and gaming culture.

Share this article
Twitter Facebook Pinterest