代码改变世界

QML 和 C++ 集成

2026-05-18 16:50  一只老老老菜鸟  阅读(10)  评论(0)    收藏  举报

C++实现逻辑(性能,访问系统底层能力,复杂算法和第三方库,多线程和并发,内存控制和优化等等方面优势),qml实现ui

qml访问C++类型的前提条件;QObject派生类。由于 QML 引擎与元对象系统的集成,任何派生类的属性、方法和信号都可能被继承,可被访问。

1.注册可实例化对象类型

向qml引擎注册C++类型,添加模块名和版本号。qml中导入模块即可使用。
1)qt5
main.cpp中添加qmlRegisterType<AddNum>("MyCppModule",1,0,"AddNum");//MyCppModule模块名,中间两个是主次版本号,AddNum是类名
2)qt6
类头文件Q_OBJECT后加QML_ELEMENT
.pro文件中添加
CONFIG+=qmltypes
QML_IMPORT_NAME = MyCppModule
QML_IMPORT_MAJOR_VERSION = 1

INCLUDEPATH += MyCppModule//如果声明该类的头文件无法从项目的包含路径访问,则可能需要修改包含路径,以便编译生成的注册代码。

共同步骤:
qml中导入模块。import MyCppModule 1.0
和任何普通对象一样被实例化和使用
函数调用,需要能被qml访问,方法public slots 或Q_INVOKABLE,属性Q_PROPERTY

 

2.使用单例类型注册单例对象

cpp实现一个单例类,向qml引擎注册C++单例类型,添加模块名和版本号
1)qt5
main.cpp中添加
MySingleton& ins = *MySingleton::instance();
qmlRegisterSingletonInstance("MyCppModule",1,0,"MySingleton",&ins);//MyCppModule模块名,中间两个是主次版本号,MySingleton是类名
2)qt6
类头文件Q_OBJECT后加QML_ELEMENT和QML_SINGLETON
将instance函数变为private,添加public static函数create
static MySingleton* create(QQmlEngine* engine,QJSEngine* jsengine){
engine->setObjectOwnership(instance(),QQmlEngine::JavaScriptOwnership);
return instance();
}
.pro文件中添加
CONFIG+=qmltypes
QML_IMPORT_NAME = MyCppModule
QML_IMPORT_MAJOR_VERSION = 1

INCLUDEPATH += MyCppModule//如果声明该类的头文件无法从项目的包含路径访问,则可能需要修改包含路径,以便编译生成的注册代码。

共同步骤:
qml中导入模块。import MyCppModule 1.0
MySingleton.func()//函数调用,需要能被qml访问,方法public slots 或Q_INVOKABLE,属性Q_PROPERTY

 

 

3.使用上下文属性将 C++ 对象嵌入到 QML 中

不止C++ 对象嵌入,还可以值嵌入
QQmlApplicationEngine engine;
AddNum am;
engine.rootContext()->setContextProperty("AddNum", &am);

qml直接使用
MySingleton.func()//函数调用,需要能被qml访问,方法public slots 或Q_INVOKABLE,属性Q_PROPERTY

C++中访问qml

QML 组件本质上是对象树,从 C++ 加载 QML文件,获取对象树的根对象,QObject *rootObject = engine.rootObjects().first(),再根据对象树访问各个对象

警告:虽然可以从 C++ 访问和操作 QML 对象,但除非用于测试和原型设计,否则不建议这样做。
QML 和 C++ 集成的一大优势在于能够将 QML 中的用户界面与 C++ 逻辑和数据集后端分离,而如果 C++ 端直接操作 QML,则此优势将无法实现。
此外,这种方法也使得在不影响其 C++ 对应部分的情况下更改 QML 用户界面变得困难。