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
}
我有一些 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
}