在QML中调用C++类
首先定义类对象时需要继承QObject,同时要包含头文件#include <QtQml>;
对于成员变量,可使用 alt+回车 自动生成两个成员函数,分别是返回变量值与设置变量值,并需要添加关于该变量改变所触发的信号函数
如对私有成员变量int m_num,利用宏定义函数
Q_PROPERTY(int num MEMBER m_num NOTIFY numChanged)
其中num为在QML中的变量名,m_num便是该类变量名,numChanged为信号函数名
信号函数的作用是为了实现在qml中的动态绑定
同时,若想在qml中使用c++类对象成员函数,可在函数前声明宏Q_INVOKEABLE,如
Q_INVOKABLE void func();
之后,在main.cpp源文件中对该类进行注册,如该类名称为QmlTest,则
qmlRegisterType<QmlTest>("MyObj", 1, 0, "QmlTest");
qmlRegisterType为模板函数,第一个参数为对类对象自定义的别名,第二、三个参数为主版本号与次版本号,第四个参数为类对象名称。注意,注册操作一定要在qml加载前完成,也就是必须在const QUrl url(...)调用前写上。注册完成便可在qml中引入
import MyObj 1.0
之后便可以控件方式去调用该类对象,以及执行其成员函数如下(通过button控件点击来执行成员函数func()以及改变成员变量num值)
QmlTest{
id: q1
num: 100
Component.onCompleted: {
console.log("num is ", num)
}
}
Button{
id: but1
objectName: "but1"
width: 100
height: 50
onClicked: {
q1.num=500
q1.func()
}
}
c++类对象发送信号并在qml连接槽函数
若c++类有信号函数
void cppsig(int i);
可在qml端通过Connections实现信号槽的绑定
Connections{
target: q1
function onCppsig(i){
console.log(i)
}
}
qml发送信号并绑定c++对象槽函数
若qml有信号函数
signal qmlsignal(int num, string str)
共有如下绑定方式
/*方式一*/
Connections{
target: window
function onQmlsignal(i,s){
q1.cppslot(i,s)
}
}
/*方式二*/
Component.onCompleted: {
qmlsignal.connect(q1.cppslot)
}
或者在main.cpp源文件中,在engine已经load完成后,即在
engine.load(url);
后,获取qml的相应控件,并通过QObject::connect进行绑定,注意,findChild中的参数为objectname,且模板一般选取QObject*即可
auto list = engine.rootObjects();
auto window = list.first();//获取根控件window
auto buttonobj = list.first()->findChild<QObject*>("but1");//获取根控件以下子控件
QObject::connect(window, SIGNAL(qmlsignal(int, QString)), &qobj, SLOT(cppslot(int, QString)));
在c++端调用qml函数
若在qml端有函数
function qmlfunc(i,s){
return "QMLFUNC"
}
在main.cpp源文件中先获取控件(操作如上)再添加变量,由于该函数有两个参数一个返回值,故
分别定义res存储返回值,arg1,arg2为参数值,并使用QMetaObject::incokeMethod函数进行调用,其中第一个参数为函数所属空间名称,第二个参数为函数名,随后是返回值与参数
QVariant res;
QVariant arg1 = 666;
QVariant arg2 = "888";
QMetaObject::invokeMethod(window,
"qmlfunc",
Q_RETURN_ARG(QVariant, res),
Q_ARG(QVariant, arg1),
Q_ARG(QVariant, arg2));//调用qml函数
qDebug()<<res;//输出函数返回值