QML与C++的交互
在QML中访问c++对象
- 首先创建一个类,这个类需继承自QObject,必须有
Q_OBJECT
宏,并加入QML_ELEMENT
宏,并且私有成员具有Q_PROPERTY
宏(可通过ALT
+ENTER
快速设置)
#include <QObject>
#include <QtQml>//注意 QML_ELEMENT 需要该头文件
class MyCppObj : public QObject
{
Q_OBJECT
QML_ELEMENT
public:
explicit MyCppObj(QObject *parent = nullptr);
int iValue() const;
void setIValue(int newIValue);
QString string() const;
void setString(const QString &newString);
//加入 Q_INVOKABLE宏的函数才可在QML端进行访问
Q_INVOKABLE void func();
private:
int m_iValue;
QString m_string;
Q_PROPERTY(int iValue READ iValue WRITE setIValue NOTIFY iValueChanged FINAL)
Q_PROPERTY(QString string READ string WRITE setString NOTIFY stringChanged FINAL)
signals:
void iValueChanged();
void stringChanged();
};
- 在cpp文件中对对象进行注册
//一定要通过创建对象来定义我们自定义的obj,对象存在于qml端
qmlRegisterType<MyCppObj>("MyCppObj.Obj",1,0,"MyCppObj");
//MyCppObj.Obj:import的库的名字
//1:主版本号
//0:次版本号
//MyCppObj:QML中类的名字
- 在qml文件中导入即可使用
import QtQuick 2.15
import QtQuick.Window 2.15
import MyCppObj 1.0
Window {
width: 640
height: 480
visible: true
MyCppObj
{
id:myObj
onIValueChanged: {}
onSstringChanged: {}
}
Component.onCompleted:
{
console.log(myObj.iValue,myObj.sstring)
myObj.func()
}
}
QML端信号绑定到C++端(在qml端进行连接)
在以上内容的基础上即完成c++类的注册之后
- 声明槽函数:
public slots:
void cppSlot(int i,QString s)
{
qDebug()<<__FUNCTION__<<i<<s;
}
- 在QML中进行连接
Window {
id:window
width: 640
height: 480
visible: true
signal qmlSignal(int i,string s)
MyCppObj
{
id:myObj
onIValueChanged: {}
onSstringChanged: {}
}
Button{
onClicked:
{
qmlSignal(10,"666")
}
}
Connections
{
target: window
function onQmlSignal(i,s)
{
myObj.cppSlot(i,s);
}
}
}
- 另一种连接方法
Component.onCompleted:
{
qmlSignal.connect(myObj.cppSlot)
}
在C++端进行连接
engine.load(url);
auto list = engine.rootObjects();//在engine.load之后
auto window = list.first();
MyCppObj *myObj = new MyCppObj();
QObject::connect(window,SIGNAL(qmlSignal(int,QString)),myObj,SLOT(cppSlot(int,QString)));
C++端信号绑定到QML端
- 在qml端进行绑定
Button{
onClicked:
{
myObj.cppSignal(10,"6")
}
}
function qmlSlot(i,s)
{
console.log("qml",i,s)
}
Connections
{
target: myObj
function onCppSignal(i,s)
{
qmlSlot(i,s);
}
}
- 在c++端进行连接
注意收发双方参数都应该是QVariant类型
QObject::connect(myObj,SIGNAL(cppSignal(QVariant,QVariant)),window,SLOT(qmlSlot(QVariant,QVariant)));
注册单例类
当我们使用qmlRegisterType
时,要通过创建对象来定义我们自定义的obj,对象存在于qml端,当我们需要类存在于全局时可使用qmlRegisterSingletonInstance
MyCppObj *myObj = new MyCppObj();
qmlRegisterSingletonInstance("MyCppObjSingle",1,0,"MyCppObj",myObj);
C++端调用QML端函数
- 获取qml对象
auto list = engine.rootObjects();
auto window = list.first();
- 准备返回值和参数
QVariant res;
QVariant arg_1 = 123;
QVariant arg_2 = "ffffff";
- 通过QMetaObject::invokeMethod调用
QMetaObject::invokeMethod(window,//获取到的qml对象
"qmlFunc",//需要调用的函数名
Q_RETURN_ARG(QVariant,res),//准备好的返回值和参数
Q_ARG(QVariant,arg_1),
Q_ARG(QVariant,arg_2));