QML和C++信号与槽

一.QML发送信号C++部分响应槽函数

        1.首先注册一个响应槽函数的类对象

                1.创建一个继承自Qbject类的类   

                     

                2. 我们需要使他让QML能认识,加入下面两句即可

                     ①包含头文件#include <QtQML>  

                     ②在类属性中加入QML_ELEMENT

                3.添加槽函数,权限设置为公有的public slots:

                

                 

                 4.注册类型  加入 qmlRegisterType<MyObject>("MyObj",1,0,"MyObject");

                MyObject 是类名, MyObj是模块名 ,1版本号,0是此版本号,MyObject是类名

                5.在qml文件中引入类型模块

                注册完成

              2.获取QML对象

                在main.cpp中 加入下面的代码,要在load函数之后

auto list = engine.rootObjects(); // 获取qml的对象
auto window = list.first();       // 拿到根对象
MyObject* test = new MyObject;    // 实例化我们cpp响应槽函数的对象
// 下面链接信号与槽,没啥说的
QObject::connect(window,SIGNAL(getcontentsig(QString)),test,SLOT(CppSlotAccept(QString))); 

                3.编写QML代码

                        1.添加信号,添加发送信号的按钮

import QtQuick
import MyObj 1.0
import QtQuick.Controls 2.15
Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")
    objectName: "window"
    id:mywindow
    signal getcontentsig(string str)

    Button{
        width:60
        height: 60
        x:50
        y:100
        onClicked: {
            mywindow.getcontentsig("发送数据");
        }
    }
}

     到这一步就完成了!!

objectName

objectName: "window"  我们每个qml生成的控件都可以拥有自己的objectName

通过以下代码

auto list = engine.rootObjects();
auto objName= list.first()->findChildren<QObject* >("MyRectangle");
//通过这种方法我们可以找到objectname 是MyRectangle控件

二.C++发送信号QML部分响应槽函数

        1.创建一个继承自Qbject类的类   

        2.我们需要使他让QML能认识 ,同上面的方法

        3.添加信号

        

       发送信号代码

        4.在main函数正常加入注册类型 

        qmlRegisterType<MyObject>("MyObj",1,0,"MyObject");

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "myobject.h"
int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    MyObject* test = new MyObject;

    qmlRegisterType<MyObject>("MyObj",1,0,"MyObject"); // 加入这句话

    QObject::connect(
        &engine,
        &QQmlApplicationEngine::objectCreationFailed,
        &app,
        []() { QCoreApplication::exit(-1); },
        Qt::QueuedConnection);
    engine.loadFromModule("TestProject", "Main");

    return app.exec();
}

                

5.在QML中引入模块 import MyObj 1.0

        QML部分代码  通过按钮触发func函数,func函数里面发送信号进而触发qml中的槽函数

import QtQuick
import MyObj 1.0
import QtQuick.Controls 2.15
Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")
    objectName: "window"
    id:mywindow
    function putcontentslot(str)
    {
        console.log("QML: "+str)
    }
    Button{
        width:60
        height: 60
        x:50
        y:100
        onClicked: {
            myobj.func()
        }
    }
    MyObject{
        id:myobj
    }

    Connections{
        target: myobj
        function onCppSig(str)
        {
           putcontentslot(str)
        }
    }
}

        完成了

        方法二:使用connect在cpp部分绑定需要注意的点是Cpp信号参数必须是QVariant

        1.按照上述方法创建一个C++ 类继承自QObject  

         2.注册一个单例

// .h   文件
public:
    static MySerialPort*  GetInstance();


// .cpp 文件
// 单例模式
MySerialPort *MySerialPort::GetInstance()
{
    static MySerialPort * instance = new MySerialPort();

    return instance;
}


// 之后在main函数中加入
//qmlRegisterSingletonInstance<类名>
//("qml引入模块名",版本号,次版本号,"类名",实例化对象);

qmlRegisterSingletonInstance<MySerialPort>("MySerial",1,0,"MySerialPort",MySerialPort::GetInstance());




         3.定义信号,这部分我卡了很长时间,最后才发现参数必须是QVariant

signals:
    void cppSig(QVariant str,QVariant index); // 定义的信号

        4.绑定信号

 // 绑定信号与槽 

    QObject::connect(MySerialPort::GetInstance(), SIGNAL(cppSig(QVariant, QVariant)), window, SLOT(iniport(QVariant, QVariant)));

        附完整代码

        .h 文件

#ifndef MYSERIALPORT_H
#define MYSERIALPORT_H

#include <QObject>
#include <QDebug>

class MySerialPort : public QObject
{
    Q_OBJECT
public:
    explicit MySerialPort(QObject *parent = nullptr);
    ~MySerialPort();
    static MySerialPort*  GetInstance();
    void receiveHander(QString str, int index);  // 发射信号的函数
signals:
    void cppSig(QVariant str,QVariant index);    // 发射信号
};

.cpp

MySerialPort::MySerialPort(QObject *parent)
    : QObject{parent}
{

}
// 单例模式
MySerialPort *MySerialPort::GetInstance()
{
    static MySerialPort * instance = new MySerialPort();

    return instance;
}

// 这部分函数发射信号
void MySerialPort::receiveHander(QString str, int index)
{
    //qDebug()<<str<<index;
    emit cppSig(str,index);
    qDebug()<<"myser:"<<str<<" "<<index;
}

 main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "myserialport.h"
#include <QObject>

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    qmlRegisterSingletonInstance<MySerialPort>("MySerial",1,0,"MySerialPort",MySerialPort::GetInstance());

    QObject::connect(
        &engine,
        &QQmlApplicationEngine::objectCreationFailed,
        &app,
        []() { QCoreApplication::exit(-1); },
        Qt::QueuedConnection);
    engine.loadFromModule("fireProject", "Main");



    auto list = engine.rootObjects(); // 获取qml的对象
    auto window = list.first();       // 拿到根对象
   
    // 绑定信号与槽  iniport QML 执行槽函数
    QObject::connect(MySerialPort::GetInstance(), SIGNAL(cppSig(QVariant, QVariant)), window, SLOT(iniport(QVariant, QVariant)));
    return app.exec();
}

       .qml部分    

import QtQuick
import QtQuick.Controls 2.15
import MySerial 1.0


Window {
    id:root
    width: 800
    height: 480
    visible: true
    title: qsTr("Hello World")
//初始化部分检测指令绑定部分

    function iniport(str,index){
        console.log(str,index);
    }

}

        方法三:使用Connects连接 直接上代码

        .h

#include <QObject>

class MyObj : public QObject
{
    Q_OBJECT
public:
    explicit MyObj(QObject *parent = nullptr);
    static MyObj* getinstance();
signals:
    void cppSig(QString str, int index);
};

.cpp 

#include "myobj.h"

MyObj::MyObj(QObject *parent)
    : QObject{parent}
{}

MyObj *MyObj::getinstance()
{
    static MyObj* my = new MyObj;
    return my;
}

.qml 

import QtQuick
import MyObj123 1.0
import QtQuick.Controls 2.15
Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    function qmlslot(str,index){
        console.log(str,index);
    }
    Button{
        width: 50
        height: 50
        x:100
        y:100
        onClicked: {
            MyObj.cppSig("Test",123);
        }
    }

    Connections{
            target: MyObj
            function onCppSig(ii,ss){
                qmlslot(ii,ss)
            }
        }

}

 main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "myobj.h"
int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    qmlRegisterSingletonInstance("MyObj123",1,0,"MyObj",MyObj::getinstance());
    QQmlApplicationEngine engine;
    QObject::connect(
        &engine,
        &QQmlApplicationEngine::objectCreationFailed,
        &app,
        []() { QCoreApplication::exit(-1); },
        Qt::QueuedConnection);
    engine.loadFromModule("Testconnect1", "Main");

    return app.exec();
}

 但是我自己多线程去写代码的时候,发现这种方法貌似有些问题,无法触发我想要的结果

三.QML如何直接调用C++部分的代码     

        1.注册C++类方法上面已经说了

        2.在C++类中加入调用函数

        3.在调用函数前加入关键字Q_INVOKABLE

        

        qml部分代码我直接粘贴了

import QtQuick
import MyObj 1.0
import QtQuick.Controls 2.15
Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")
    MyObject{
        id:myo
    }

    Button{
        width:60
        height: 60
        x:50
        y:100
        onClicked: { 
            myo.func();
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值