首页 > 解决方案 > qml插件c++应该如何使用单例?

问题描述

我以 MyTestPlugin 的名义创建了 Qt Quick 2Extension Plugin ,在里面我以 MySingleton 的名义创建了 c++ 文件,在 MySingleton 类中添加了 QML_SINGLETON 。

我的单例.hpp

#ifndef TESTSINGLETON_H
#define TESTSINGLETON_H

#include <QQuickItem>

class TestSingleton : public QQuickItem
{
    Q_OBJECT
    Q_DISABLE_COPY(TestSingleton)
    QML_SINGLETON

public:
    explicit TestSingleton(QQuickItem *parent = nullptr);
    ~TestSingleton() override;

signals:
    void testSignal();

public:
    Q_INVOKABLE int testMethod();
};

#endif // MUSEAGORA_H

然后在 MyTestPlugin.cpp 中添加以下代码

void MyTestPlugin::registerTypes(const char *uri)
{
    // @uri TestSingleton
    qmlRegisterSingletonInstance<TestSingleton>(uri, 1, 0, "TestSingleton", new TestSingleton());
}

使用 qmlplugindump 创建 plugins.qmltypes:

import QtQuick.tooling 1.2

Module {
    dependencies: [
        "QtGraphicalEffects 1.12",
        "QtQml 2.14",
        "QtQml.Models 2.2",
        "QtQuick 2.9",
        "QtQuick.Controls 1.5",
        "QtQuick.Controls.Styles 1.4",
        "QtQuick.Extras 1.4",
        "QtQuick.Layouts 1.1",
        "QtQuick.Window 2.2"
    ]
    Component {
        name: "TestSingleton"
        defaultProperty: "data"
        prototype: "QQuickItem"
        exports: ["MyTestPlugin/TestSingleton 1.0"]
        isCreatable: false
        isSingleton: true
        exportMetaObjectRevisions: [0]
        Signal { name: "testSignal" }
        Method { name: "testMethod"; type: "int" }
    }
}

在 qml 中新建一个项目 import MyTestPlugin 1.0 并调用 MyTestPlugin.testMethod() 输出如下

<Unknown File>: Registered object must live in the same thread as the engine it was registered with
<Unknown File>: qmlRegisterSingletonType(): "TestSingleton" is not available because the callback function returns a null pointer.
qrc:/main.qml:285: TypeError: Property 'testMethod' of object [object Object] is not a function

插件可以使用 C++ 单例吗?我应该如何正确使用?

标签: qtqml

解决方案


我自己找到了路

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

    TestSingleton *e = new TestSingleton();
    return e;
}

void MuseAgoraPlugin::registerTypes(const char *uri)
{
    // @uri TestSingleton
    qmlRegisterSingletonType< TestSingleton >(uri, 1, 0, "TestSingleton", test_singleton_type_provider);
}

推荐阅读