将C++类注册到QML
Q_GLOBLE_STATIC
由Qt负责线程安全与懒加载的创建单例对象
Q_GLOBAL_STATIC(Type, instanceName); // 声明全局静态对象
Q_GLOBAL_STATIC_WITH_ARGS(Type, instanceName, Args...); // 带参数的构造
-
Type:单例类的类型。 instanceName:静态实例的变量名。Args...:构造函数参数(可选)。
Q_GLOBAL_STATIC(A, aInstance); // 由qt负责构造和提供一个静态单例实例
class A{
static A* getInstance(){
return &aInstance;
}
/*
相当于
static A* getInstance(){ //
static aInstance; // 构造可能多线程不安全,将其交给qt负责
return &aInstance;
}
*/
}
手动注册
非单例
实现方法:**qmlRegisterType<MyComponent>
1. 注册类型
// 注册到 QML
qmlRegisterType<MyComponent>("com.mylib", 1, 0, "MyComponent");
// C++ 类定义
class MyComponent : public QObject {
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName)
public:
explicit MyComponent(QObject *parent = nullptr) : QObject(parent) {}
QString name() const { return m_name; }
void setName(const QString &name) { m_name = name; }
private:
QString m_name;
};
// 注册到 QML
qmlRegisterType<MyComponent>("com.mylib", 1, 0, "MyComponent");
2. 使用
非单例对象需要在QML作组件实例化,然后才能访问
// QML 中使用(每次创建新实例)
import com.mylib 1.0 // 导入
MyComponent {
id: component1
name: "Instance 1"
}
MyComponent {
id: component2 // 独立的新实例
name: "Instance 2"
}
单例
实现方法:qmlRegisterSingletonType<ClassName> + 工厂方法
所有 QML 组件访问的是同一个实例,需通过工厂函数控制实例化。
1. 工厂函数签名必须是
static QObject* create(QQmlEngine*, QJSEngine*) {
static ConfigManager instance; // 全局唯一实例
return &instance;
}
2. 注册到引擎中
// main.cpp :: main()
// 注册到 QML
qmlRegisterSingletonType<ConfigManager>(
"com.mylib",// 包名
1, // 版本
0, // 版本
"ConfigManager", // QML中访问使用的类型名
[](QQmlEngine*, QJSEngine*) -> QObject* { return ConfigManager::create(nullptr, nullptr); // 类工厂方法
}
);
3. QML中访问
单例组件直接通过类名访问
// QML 中使用(全局共享实例)
import com.mylib 1.0
Text {
// 单例对象不实例化为组件,直接通过类名访问
text: ConfigManager.theme // 所有组件访问同一实例
}
是否多QML引擎间共享单例:qmlRegisterSingletonType控制每个实例只在QML引擎使用工厂类获取一次。如果通过工厂方法每次都返回相同实例,则就是多QML引擎共享的,如果每次返回新实例,就是多引擎不共享的。
QML_ELEMENT 宏(自动化注册)
在cmake中配置统一版本,无需配置类型名等,简化开发代码。
非单例对象
1. 包含宏
// MyClass.h
#include <QObject>
class MyClass : public QObject {
Q_OBJECT
QML_ELEMENT
// QML_NAMED_ELEMENT(MyClass) // 指定QML中使用的类型名,可省略,省略则自动使用C++类名作为QML类型名
// ...
};
2. CMake中包含文件,配置模块信息
qt_add_qml_module(MyModule
URI "MyModule" // QML中使用的包名
VERSION 1.0 // 版本
SOURCES myclass.h myclass.cpp // 文件
)
3. 使用
非单例要实例化组件然后通过组件访问
// QML 中直接使用类名
import MyModule 1.0
MyClass { // 类型名与 C++ 类名一致
//...
}
单例对象
1. 包含宏
// MyClass.h
#include <QObject>
class MyClass : public QObject {
Q_OBJECT
QML_ELEMENT // 注册QML对象
QML_SINGLETON // 自动注册为QML单例
// ...
};
2. CMake中包含文件,配置模块信息
qt_add_qml_module(MyModule
URI "MyModule" // QML中使用的包名
VERSION 1.0 // 版本
SOURCES myclass.h myclass.cpp // 文件
)
3. 使用
直接通过类名访问单例对象
// QML 中直接使用类名
import MyModule 1.0
Rectangle {
name: MyClass.value
}
暴露属性
属性绑定
使用Q_PROPERTY要提供读写方法和信号,写用来在事件中设置属性,读和信号用来将数据绑定到组件,并通过信号触发读方法更新视图,同时信号也可以捕获处理。
先来看数据流向

整体是一个单向绑定 事件->Model->View
QML将一个属性绑定 cpp对象方法
Text{
text: cppobj.value // 从 js = cppobj.value 调用的是cppobj.Getter方法
onChange:{
cppobj.value = value // 这里赋值操作时setter方法
}
}
cppobj.value 其底层会调用cppobj.Getter方法获取数据,并且绑定valueChange信号。
cpp值改变时,会发送信号触发Getter去更新数据(set方法emit信号,如果不发送信号则不会去触发视图更新)
// MyClass.h
#include <QObject>
class MyClass : public QObject {
Q_OBJECT
QML_ELEMENT // 自动注册为QML类型
// 暴露属性:类型、名称、读方法、写方法、通知信号
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
public:
explicit MyClass(QObject* parent = nullptr) : QObject(parent) {}
// Getter方法
QString name() const { return m_name; }
// Setter方法
void setName(const QString& name) {
if (m_name == name) return;
m_name = name;
emit nameChanged(); // 触发通知信号到QML
}
signals:
void nameChanged();
private:
QString m_name = "Default";
};
信号捕捉
可以在QML的C++组件中捕捉信号并处理
MyClass{
onNameChanged:{ // on+信号名 捕捉信号
// ...
}
}
方法绑定
使用 Q_INVOKABLE 宏
// MyClass.h
#include <QObject>
#include <QString>
class MyClass : public QObject {
Q_OBJECT
QML_ELEMENT
public:
explicit MyClass(QObject* parent = nullptr) : QObject(parent) {}
// 暴露普通方法
Q_INVOKABLE QString formatMessage(const QString& text, int count) {
return QString("%1: %2 items").arg(text).arg(count);
}
// 暴露槽函数(无需Q_INVOKABLE,自动可见)
public slots:
void reset() {
m_value = 0;
emit valueChanged();
}
// 暴露信号处理函数
void onButtonClicked() {
qDebug() << "Button clicked!";
}
signals:
void operationCompleted(bool success);
};

浙公网安备 33010602011771号