qml与c++交互通信(三)c++端发送信号并绑定qml端槽函数

在本次的内容中,主要实现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)
        }
    }
}

上述代码均能正常绑定信号和槽函数并正确输出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值