Ссылка на экземпляр класса QML Singleton? - PullRequest
0 голосов
/ 28 апреля 2018

Я создал класс с именем LoginService. Я зарегистрировал его в QT QML-файле с помощью qmlRegisterSingletonType, теперь проблема в том, что я не могу получить экземпляр loginservice, экземпляр которого создан QML. Мой текущий код C ++:

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 Ответ

0 голосов
/ 28 апреля 2018

Если вы хотите получить доступ к синглтону из C ++, создайте метод, который возвращает экземпляр, отличный от 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"
}
...