在本次的内容中,主要实现c++端定义一个信号,并发送这个信号,来绑定qml端的槽函数。
1、c++端发送信号绑定qml端槽函数
我们首先在qml端定义一个槽函数,如下:
同时需要在c++端定义一个信号,信号在myobj.h头文件中定义如下:
有了信号的槽函数后,我们就需要做的是绑定信号和槽函数。在绑定关系完成后,发送信号即可触发对应的槽函数。
import QtQuick
import QtQuick.Window
import QtQuick.Controls
import com.mycompany.Myobj
ApplicationWindow {
id: mywin
width: 500
height: 400
visible: true
title: qsTr("Hello World")
function qmlslot(i, s){
console.log(i+" "+s)
}
MyObj123{
id:myo1
mydata: 40
}
Button{
width: 60
height: 60
onClicked: {
myo1.cppsig(18,"dzg")
}
}
Connections{
target: myo1
function onCppsig(ii,ss){
qmlslot(ii,ss)
}
}
}
上述代码是qml端的代码。使用Connections函数来绑定信号和槽函数,target是qml端创建的c++对象myo1,槽函数是onCppsig函数,并在该函数中调用qmlslot槽函数。对于信号的触发,在button按钮点击后触发信号。这样做可以实现信号槽的绑定。
但上述做法,有一个小问题,就是c++端定义的信号仍在是在qml端触发的,因此我们换成在c++端触发信号,这个也比较简单,使用emit关键字就可以了。做法如下:
在Q_INVOKABLE修饰的函数中触发信号,fun()方法的代码如下:
并在qml端代码调用fun()方法就可以了。
在button按钮的点击事件后,调用这个函数。
2、使用qmlRegisterSingletonInstance注册单例对象
上面的方法使用qmlRegisterType<MyObj>来向qml端注册我们定义的c++类型,并需要在qml端的代码中实例化该对象,实例化对象后,才可以使用该对象的方法和变量属性等。
qmlRegisterType<MyObj>("com.mycompany.Myobj",1,0,"MyObj123");
//在c++端注册qml端使用的类型
import com.mycompany.Myobj//引入该类型模块
ApplicationWindow {
MyObj123{//实例化该类型
id:myo1
mydata: 40
}
上述的介绍中,可以看出,必须要通过实例化才可以使用对象的方法,那么如何做到不需要实例化就可以使用对象的方法和属性呢?
使用qmlRegisterSingletonInstance来注册一个单例的对象,在qml端代码中不需要实例化就可以对该类型的方法和属性进行访问。
在c++中创建自定义类型的头文件中添加获取单例模式的声明:
在自定义类型的源文件中添加获得单例对象的定义代码:
并在main.cpp主程序中添加qmlRegisterSingletonInstance来注册单例对象。具体代码如下:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include<QQmlContext>
#include <QIcon>
#include "myobj.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
//qmlRegisterType<MyObj>("com.mycompany.Myobj",1,0,"MyObj123");
qmlRegisterSingletonInstance("com.mycompany.Myobj",1,0,"MyObj123",MyObj::getInstance());
const QUrl url(QStringLiteral("qrc:/quickTest/Main.qml"));
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreationFailed,
&app,
[]() { QCoreApplication::exit(-1); },
Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
qmlRegisterSingletonInstance的第四个参数为我们需要在qml端使用的单例对象。有了这个单例对象后,就不要再qml端实例化该对象了。可以直接通过MyObj123来直接使用对象的方法和属性。
import QtQuick
import QtQuick.Window
import QtQuick.Controls
import com.mycompany.Myobj
ApplicationWindow {
id: mywin
width: 500
height: 400
visible: true
title: qsTr("Hello World")
function qmlslot(i, s){
console.log(i+" "+s)
}
Button{
width: 60
height: 60
onClicked: {
MyObj123.fun();
}
}
Connections{
target: MyObj123
function onCppsig(ii,ss){
qmlslot(ii,ss)
}
}
}
上述代码均能正常绑定信号和槽函数并正确输出。