【Qt6 Quick】C++类使用宏注册到QML

QML_ELEMENT

自动把该类注册到 QML 系统,否则需要你手动调用 qmlRegisterType<Interface>()

QML_SINGLETON

只调用一次构造或工厂方法作为之后QML所有组件的单例对象。如果不加,QML每次组件使用都会新创建对象。

Q_GLOBLE_STATIC

由Qt负责线程安全懒加载的创建单例对象

非单例

实例化

1、C++ 类定义

// interface.h
#pragma once

#include <QObject>
#include <QQmlEngine>
#include <QtQml>

class Interface : public QObject
{
    Q_OBJECT
    QML_ELEMENT         // 注册为 QML 类型

public:
    explicit Interface(QObject *parent = nullptr);

    Q_INVOKABLE QString sayHello(); // 可供 QML 调用
};

// interface.cpp
#include "interface.h"

Interface::Interface(QObject *parent) : QObject(parent) {}

QString Interface::sayHello() {
    return "Hello from C++";
}

2、注册到Qt模块

# 或者,如果使用 CMake,注册 module
qt_add_qml_module(your_target
    URI MyApp
    VERSION 1.0
    SOURCES
        interface.cpp interface.h
)

3、在 QML 中使用

// main.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
import MyApp 1.0 // URI VERSION

ApplicationWindow {
    visible: true
    width: 400
    height: 300
    title: "Interface Singleton Demo"

    Text {
        anchors.centerIn: parent
        text: Interface.sayHello() // 调用 C++ 的方法
    }
}

单例

多QML引擎共享

1、C++ 类定义

使用 Q_GLOBLE_STATIC 创建线程安全的共享单例对象

在使用 QML_SINGLETON 时,工厂方法 (create) 的签名必须与 QML_SINGLETON 宏期望的签名一致。也就是说,它必须是 静态方法,并且接受两个参数:QQmlEngine* 和 QJSEngine*
如果存在这个签名,就是多QML引擎共享的单例,否则QML会调用默认构造创建非共享的单例实例

class Interface : public QObject
{
    Q_OBJECT
    QML_ELEMENT // 注册到QML
    QML_SINGLETON // QML单例
public:
    explicit Interface(QObject *parent = nullptr);

	Q_INVOKABLE QString sayHello(); // 可供 QML 调用

    // 静态工厂类
    static Interface *create(QQmlEngine*,QJSEngine *)
    
}
#include "Interface.h"

// 类,生成单例对象的函数
Q_GLOBAL_STATIC(Interface,s_interface) // 懒加载生成单例对象

QString Interface::sayHello() {
    return "Hello from C++";
}

// 工厂函数
Interface *Interface::create(QQmlEngine*,QJSEngine *)
{
    return s_interface(); // 使用Q_GLOBAL_STATIC定义的生成单例对象的函数
}

2、注册到Qt模块

# 或者,如果使用 CMake,注册 module
qt_add_qml_module(your_target
    URI MyApp
    VERSION 1.0
    SOURCES
        interface.cpp interface.h
)

3、在 QML 中使用

// main.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
import MyApp 1.0 // URI VERSION

ApplicationWindow {
    visible: true
    width: 400
    height: 300
    title: "Interface Singleton Demo"

    Text {
        anchors.centerIn: parent
        text: Interface.sayHello() // 调用 C++ 的方法
    }
}

多QML引擎不共享

直接不提供 static Interface *create(QQmlEngine*,QJSEngine *) 静态工厂函数即可,Qt自动调用默认构造去创建

class Interface : public QObject
{
    Q_OBJECT
    QML_ELEMENT // 注册到QML
    QML_SINGLETON // QML单例
public:
    explicit Interface(QObject *parent = nullptr);

	Q_INVOKABLE QString sayHello(); // 可供 QML 调用

}
#include "Interface.h"

// 类,生成单例对象的函数
Q_GLOBAL_STATIC(Interface,s_interface) // 懒加载生成单例对象

QString Interface::sayHello() {
    return "Hello from C++";
}

posted @ 2025-05-11 15:56  丘狸尾  阅读(274)  评论(0)    收藏  举报