如何理解 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
1400 0
|
4月前
|
JavaScript 前端开发
Object.freeze() 和 const 的区别详解
【8月更文挑战第31天】
34 0
|
7月前
|
JavaScript
vue2中$set的原理_它对object属性做了啥?
vue2中$set的原理_它对object属性做了啥?
67 1
|
7月前
|
Dart JavaScript 安全
Flutter的setState的使用注意事项以及报错The method ‘setState‘ isn‘t defined for the type
Flutter的setState的使用注意事项以及报错The method ‘setState‘ isn‘t defined for the type
Dart报The return type ‘bool‘ isn‘t a ‘void‘, as required by the closure‘s context
Dart报The return type ‘bool‘ isn‘t a ‘void‘, as required by the closure‘s context
Array.prototype.includes() 原型调用用法案例讲解
Array.prototype.includes() 原型调用用法案例讲解
119 2
|
Dart 索引
[Flutter]足够入门的Dart语言系列之变量的类型:bool、String、num、List、Set和Map
变量的类型指的是变量的特性或特征,比如表示数字类型、文本类型、集合类型等,表示的是一类数据。 Dart提供以下类型:int, double、String、List、Set、Map、null...
683 0
[Flutter]足够入门的Dart语言系列之变量的类型:bool、String、num、List、Set和Map
在main函数中创建新对象时出错 No enclosing instance of type ooo is accessible. Must qualify the allocation with a
在main函数中创建新对象时出错 No enclosing instance of type ooo is accessible. Must qualify the allocation with a
在main函数中创建新对象时出错 No enclosing instance of type ooo is accessible. Must qualify the allocation with a
class_create函数源码分析
class_create函数源码分析