Qt 5.4/QML:如何将自定义 C++ class 正确实现为全局 QML 单例实例并为其信号实现代码(在 QML 中)?

Qt 5.4/QML: How do I correctly implement a custom C++ class as a global QML singleton instance and implement code for its signals (in QML)?

我有一些 C++ class,我想在 QML 中注册,这样我就可以从 QML 代码访问它,并为 QML 开发人员提供一个安全的 API - 同时保留复杂的东西 "under the hood" 并从 QML 的角度隐藏。

到目前为止,我的习惯 class 是这样写的:


main.cpp

static QObject *myapi_singletontype_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
{
    Q_UNUSED(engine)
    Q_UNUSED(scriptEngine)
    MyApi *apiInstance = new MyApi();
    return apiInstance;
}


int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    qmlRegisterSingletonType<MyApi>("com.example.myapi", 1, 0, "MyApi", myapi_singletontype_provider);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("http://server.com/myqml.qml")));
    return app.exec();
}

MyApi.h

#ifndef MyApi_H
#define MyApi_H

#include <QObject>
#include <QtNetwork>
#include <QtCore/QDebug>
#include <QtCore/QObjectList>

class MyApi : public QObject
{
    Q_OBJECT

public:
    explicit MyApi(QObject *parent = 0);
    ~MyApi();


signals:
    void downloadStarted(const QString &uuid);
    void downloadFinished(const QString &uuid);
    void downloadError(const QString &uuid, const QString &errorText);
    void downloadProgress(const QString &uuid, const float progress);

public slots:
    void downloadArchiveInBackground(const QString &uuid);


};

#endif // MyApi_H

MyApi.cpp

#include "MyApi.h"

void MyApi::downloadArchiveInBackground(const QString &uuid) {
    // I would like to connect these signals to JS methods in QML!
    emit downloadStarted(uuid);
    emit downloadProgress(uuid, 0.3);
}

QML(伪)

MyApi {
    id: myapi
    onDownloadStarted: {
        console.log("OK STARTED")
        dialogDownload.open()
    }
}

其实我不知道如何实现这个。我知道我在这里创建了一个实例,并且使用 Singletons 这不是必需的,因为它是一个单例实例 - 但我需要一些关于如何在 QML 中实现我从 C++ 发出的信号处理程序的指针。

您可以使用 Connection QML 类型。

import com.example.myapi 1.0

Connections {
    target: MyApi
    onDownloadFinished: //do something
}