总体思路:在C++ Qt中增加一个类,并在qml引擎加载前实例化。然后通过Qt提供的接口qmlRegisterSingletonInstance
将实例化好的C++对象注册到qml中,然后在qml中使用注册好的名称来调用C++类对象接口。
具体步骤如下:
1、定义C++类
对C++类的要求
即C++类及其成员函数需要满足如下需求后才能别qml所识别和调用:
-
类必须从
QObject
或QObject
的派生类继承 -
使用
Q_OBJECT
宏 -
普通成员函数必须使用
Q_INVOKABLE
宏进行前置声明。信号、槽及QT属性不需要增加这个声明,也可以被qml调用。
C++类代码实现
class MyClass : public QObject {
Q_OBJECT
public:
MyClass(QString info) : m_info(info) {}
Q_INVOKABLE QString printInfo();
private:
QString m_info;
};
QString MyClass::printInfo()
{
qDebug()<<"info: "<<m_info;
return m_info;
}
2、注册C++类
方法一:使用Qt提供的接口qmlRegisterSingletonInstance
将实例化好的C++对象注册到qml中,注意需要在qml引擎加载前注册。
如下是qmlRegisterSingletonInstance
接口的说明:
int qmlRegisterSingletonInstance(
const char *uri, // 导出的名称,qml中使用import url来引用
int versionMajor, // 主版本号
int versionMinor, // 小版本号
const char *typeName, // qml中使用此名称作为C++的对象来使用
QObject *cppObject // C++类的实例指针
)
注册实现代码
MyClass myInfo(QString("myclss test"));
qmlRegisterSingletonInstance("qml_qt_com.myclass", 1, 0, "MyclassApi", &myInfo);
通过qml引擎的属性注册C++类
方法二:使用qml引擎提供的属性接口注册,如下:
engine.rootContext()->setContextProperty("MyclassApi", &myInfo);
MyclassApi
就成为了QML中的全局变量,你可以直接使用它内部的各种元数据(信号、槽、属性、枚举类型等等)
3、Qml调用
- qml中需要导入注册的C++实例类名称
- 使用注册的
typeName
作为C++对象来调用成员函数
实现如下:
import qml_qt_com.myclass 1.0 // 导入模块,使用qml引擎的属性注册时不需要如此导入
Button {
text: "Quit";
objectName: "quitButton";
Layout.leftMargin: 10
onClicked: {
// 调用C++接口
console.log("clicked info: "+MyclassApi.printInfo())
}
}
4、运行
点击button
后,输出如下数据:
info: "myclss test" // c++输出
qml: clicked info: myclss test // qml输出
完整实现可以,关注公众号并回复:“qml_2”获取。