如何理解 QML_ELEMENT QML_SINGLETON staic Foo *create(QQmlEngine *, QJSEngine *){return s instance; }

简介: 如何理解 QML_ELEMENT QML_SINGLETON staic Foo *create(QQmlEngine *, QJSEngine *){return s instance; }

如何理解

QML_ELEMENT 
 QML_SINGLETON 
 staic Foo *create(QQmlEngine *, QJSEngine *){
  return s_instance;
 }

这段代码涉及在 Qt 中使用 QML 元素和单例模式,结合了 QML_ELEMENT 和 QML_SINGLETON 宏以及一个静态工厂方法。下面是对这些概念和代码的解释。

关键概念

  1. QML_ELEMENT:

QML_ELEMENT 是一个宏,用于将一个 C++ 类暴露给 QML,使其可以作为 QML 类型使用。使用这个宏后,类可以直接在 QML 中被引用和实例化,类似于 QML 中的内置元素。
这个宏通常放在类声明中,如下所示:

class Foo : public QObject {
    Q_OBJECT
    QML_ELEMENT
    // 类的声明...
};

这使得 Foo 类可以在 QML 文件中直接使用。

  1. QML_SINGLETON:
    QML_SINGLETON 是另一个宏,它与 QML_ELEMENT 类似,但用于将一个类注册为单例,这意味着这个类在 QML 环境中只会有一个实例。

配合 QML_SINGLETON 使用时,QML 中对该类型的引用总是指向相同的实例,而不是每次都创建新的实例。

  1. 静态工厂方法 create(QQmlEngine *, QJSEngine *):

这是一个静态方法,通常与 QML_SINGLETON 一起使用,用于提供对单例对象的访问。

参数 QQmlEngine* 和 QJSEngine* 是 QML 引擎和 JavaScript 引擎的指针,通常在这个静态方法中没有被使用,但它们是 QML 注册时的要求。

该方法返回一个指向 Foo 类静态实例的指针(例如 s_instance),确保 QML 中使用的总是同一个 Foo 实例。

代码片段解释

static Foo *create(QQmlEngine *, QJSEngine *) {
    return s_instance;
}

静态方法:这个 create 方法是静态的,意味着它属于类本身,而不是某个具体的对象实例。

返回单例实例:return s_instance; 返回的是一个指向单例对象的指针 s_instance。s_instance 应该是在 Foo 类中定义的一个静态成员变量,确保在整个程序生命周期内只有一个 Foo 实例。


实现过程

假设有一个 Foo 类,并希望将其注册为 QML 中的单例元素:

// Foo.h
#ifndef FOO_H
#define FOO_H

#include <QObject>
#include <QQmlEngine>
#include <QJSEngine>

class Foo : public QObject
{
    Q_OBJECT
    QML_ELEMENT       // 将 Foo 暴露给 QML
    QML_SINGLETON     // 将 Foo 注册为单例

public:
    // 静态方法,返回单例实例
    static Foo* create(QQmlEngine*, QJSEngine*) {
        static Foo s_instance;  // 创建并持有一个单例实例
        return &s_instance;
    }

private:
    Foo() {}  // 私有构造函数,防止外部实例化
};

#endif // FOO_H

在 QML 中使用

在 main.cpp 文件中,将单例注册到 QML 引擎:

// main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "Foo.h"

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

    // 通过静态工厂函数注册 QML 单例
    qmlRegisterSingletonType<Foo>("com.example.foo", 1, 0, "Foo", &Foo::create);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

然后在 QML 文件中,可以这样使用 Foo:

// main.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
import com.example.foo 1.0

ApplicationWindow {
    visible: true
    width: 640
    height: 480

    // 使用 Foo 单例
    Text {
        text: Foo.someProperty
    }
}

总结

QML_ELEMENT:允许类作为 QML 元素使用。

QML_SINGLETON:确保类在 QML 中只实例化一次,作为单例使用。

create 静态方法:用于提供 QML 引擎访问单例实例的接口。

通过这种方式,Foo 类被暴露为 QML 元素,并且作为单例被使用,从而确保整个应用中 Foo 只有一个实例。这种设计在需要共享数据或状态的场景中特别有用。

目录
相关文章
Vue3接口数据报错TypeError: target must be an object
Vue3接口数据报错TypeError: target must be an object
1267 0
react-Native init初始化项目报错”TypeError: cli.init is not a function“
react-Native init初始化项目报错”TypeError: cli.init is not a function“
628 1
|
4月前
|
JavaScript
vue2中$set的原理_它对object属性做了啥?
vue2中$set的原理_它对object属性做了啥?
43 1
|
4月前
|
Dart JavaScript 安全
|
11月前
|
开发者
如何使用 ABAP Function Module SEO_CLASS_CREATE_COMPLETE 创建 ABAP class
如何使用 ABAP Function Module SEO_CLASS_CREATE_COMPLETE 创建 ABAP class
|
12月前
|
Web App开发 API 开发者
关于 SAP UI5 Context.prototype.delete 方法的输入参数 Group ID 的细节
关于 SAP UI5 Context.prototype.delete 方法的输入参数 Group ID 的细节
Flutter的setState的使用注意事项以及报错The method ‘setState‘ isn‘t defined for the type
Flutter的setState的使用注意事项以及报错The method ‘setState‘ isn‘t defined for the type
Array.prototype.includes() 原型调用用法案例讲解
Array.prototype.includes() 原型调用用法案例讲解
110 2
undefined reference to `swr_init+
undefined reference to `swr_init+
104 0