Qt 注册 C++ 给 QML 调用的几种方式

1. Q_INVOKABLE / slots - 注册方法

复制代码
class MyHelper : public QObject {
    Q_OBJECT
public:
    Q_INVOKABLE QString getName() { return m_name; }
    
public slots:
    void doSomething(int value);
};

2. Q_PROPERTY - 注册属性

复制代码
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)

QML 中直接用 obj.name 访问。

3. qmlRegisterType - 注册可实例化类型

复制代码
// main.cpp
qmlRegisterType<MyClass>("MyModule", 1, 0, "MyClass");

// QML
import MyModule 1.0
MyClass { }

4. qmlRegisterSingletonType - 注册单例

复制代码
qmlRegisterSingletonType<MyApi>("MyModule", 1, 0, "MyApi", 
    [](QQmlEngine*, QJSEngine*) -> QObject* {
        return new MyApi;
    });

QML 中直接用 MyApi.method() 调用。

5. qmlRegisterUncreatableType - 注册枚举/工具类

复制代码
qmlRegisterUncreatableType<MyEnums>("MyModule", 1, 0, "MyEnums", "无法创建");

// 枚举要加 Q_ENUM
class MyEnums : public QObject {
    Q_OBJECT
public:
    enum Status { OK, Error };
    Q_ENUM(Status)
};

6. Qt 6 新语法 - QML_ELEMENT(推荐)

复制代码
// C++ 头文件
class MyHelper : public QObject {
    Q_OBJECT
    QML_ELEMENT          // 自动注册
    QML_SINGLETON        // 单例
    Q_PROPERTY(int count READ count NOTIFY countChanged)
    
    Q_INVOKABLE void refresh();
};

# CMakeLists.txt
qt6_add_qml_module(app
    URI MyModule
    VERSION 1.0
    SOURCES myhelper.h myhelper.cpp
)

对比总结:

方式 用途 Qt版本
Q_INVOKABLE 注册方法 全部
Q_PROPERTY 注册属性 全部
qmlRegisterType 可实例化类 Qt4+
qmlRegisterSingletonType 单例 Qt5+
QML_ELEMENT 自动注册(推荐) Qt6

面试回答:

"主要有三种方式:Q_INVOKABLE和slots注册方法、Q_PROPERTY注册属性、qmlRegister系列函数注册类型。Qt6推荐用QML_ELEMENT宏配合CMake自动注册,更简洁。"

READ name 里的 name 是 getter 函数名,必须自己定义

完整写法:

复制代码
class Person : public QObject {
    Q_OBJECT
    Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
    
public:
    // READ 函数 - 必须定义
    QString name() const { return m_name; }
    
    // WRITE 函数 - 必须定义
    void setName(const QString &name) {
        if (m_name != name) {
            m_name = name;
            emit nameChanged();  // 触发信号
        }
    }
    
signals:
    // NOTIFY 信号 - 必须定义
    void nameChanged();
    
private:
    QString m_name;  // 成员变量
};

各部分说明:

部分 含义 是否必须定义
READ name getter函数名 ✅ 必须定义
WRITE setName setter函数名 ❌ 可选,只读属性不需要
NOTIFY nameChanged 值变化信号 ❌ 可选,但推荐加上

简写形式(只读属性):

复制代码
Q_PROPERTY(int count READ count CONSTANT)
// CONSTANT 表示值不变,不需要 NOTIFY

int count() const { return m_count; }

面试注意:

Qt 不会自动生成这些函数,都要手写。不像 C# 的 property 或 Kotlin 那样有自动合成。

相关推荐
hetao17338371 分钟前
2026-08-21~23 hetao1733837 的刷题记录
c++·算法
夏之小星星9 分钟前
【找回mysql被删除数据】
数据库·sql·mysql
__zRainy__17 分钟前
Node系列 · ORM:Sequelize 模型
数据库·后端·node.js
whcyhhh19 分钟前
头歌实践教学平台:数据科学与大数据技术导论(五)
大数据·数据库·python
大鹏说大话30 分钟前
用 Python 与 DeviceAtlas 构建自动化设备数据库
数据库·python·自动化
肠畔码农36 分钟前
深度解密 Redis 核心引擎:从 MULTI/EXEC 事务机制到 EVAL 脚本的原子性演进
数据库·redis·junit
lailai04101 小时前
定制化企业网盘与标准化方案
数据库
PHP实战开发录1 小时前
AI接口结构化输出解析异常排查记录
数据库·安全·ai·php·开发
JAVA面经实录9171 小时前
MySQL问题定位与性能优化完整知识体系
java·jvm·数据库·mysql·性能优化
JL152 小时前
如何用 MySQL 持久化、历史快照与游标实现多步 Redo/Undo
前端·数据库·mysql