QT-信号与槽(灵魂)

1-首先玩家自己手写信号和槽(通过connect函数将 两个函数签名相同的方法进行绑定)具体表现为一个信号和一个槽函数绑定起来,一旦触发 发射信号就会执行槽函数的内容.

2-可以直接看每一个代码块的头部注释就是学习中记录下来的思想

比如按下按钮去触发一个信号然后去执行你想要的业务代码。

下面的例子不再一个main函数中说明一下:
(因为头文件.h和源文件.cpp是分开写的看起来可能会乱乱的)
Xobject  作为一个各种信号的类
xobject_ 作为一个对应各种槽函数的类
#include <QObject>

class xobject_ : public QObject
{
    Q_OBJECT
public:
    explicit xobject_(QObject *parent = nullptr);

    ~xobject_();
signals:

public slots:
    void slot_say_a(); //设置槽函数
    void slot_say_a(QString message); 
    void slot_say_a(QString message,QString message1);
    void slot_say_b(QString message,QString message1);
};
------------------------------上面是头文件,下面是源文件--------------------------------
#include "xobject_.h"
#include <QDebug>
xobject_::xobject_(QObject *parent) : QObject(parent)
{

}

xobject_::~xobject_()
{
    qDebug()<<"析构函数~xobject:x_";
}

void xobject_::slot_say_a()
{
    qDebug()<<"slot_say_a无参";
}

void xobject_::slot_say_a(QString message)
{
    qDebug()<<"slot_say_aaa "<<sender(); //sender()获取 信号指针,(有可能返回空指针)
}

void xobject_::slot_say_a(QString message, QString message1)
{
    //重载函数
}

void xobject_::slot_say_b(QString message, QString message1)
{
    qDebug()<<"slot_say_bbb";
}

#include <QObject>     // Xobject 头文件

class Xobject : public QObject
{
    Q_OBJECT
public:
    explicit Xobject(QObject *parent = nullptr);

    void fashe(QString message);


    //moc会检测它
signals:
    void say_a(QString message); //设置信号函数
    void say_a(QString message,QString message1); 
    void say_b(QString message,QString message1);

    //
public slots:
};
        
#include "xobject.h"   // Xobject 源文件
#include <QDebug>
Xobject::Xobject(QObject *parent) : QObject(parent)
{

}

void Xobject::fashe(QString message)
{
    qDebug()<<"发射strat";
    emit say_a(message);//发射信号 emit可以不写,写上方便阅读
    qDebug()<<"发射end";
}

以下是main函数内容 ↓ ↓ ↓ ↓ ↓

/* 信号和槽
*   1-简单写一个信号和槽(通过connect函数将 两个函数签名相同的方法进行绑定):信号发射 槽函数做具体指令
*   2-几种实现信号槽的方式
*       2-1:connect(x,SIGNAL(say_a(QString)),x_,SLOT(slot_say_a(QString)));//不受重载影响推荐
*       2-2:成员函数指针-弊端是出现重载的槽函数无法正常区分 需要使用函数指针明确类型
*       2-3:Function 拉姆达表达式相当灵活 说走就走的函数对于单次使用最好的实现方式
*       2-4:QMetaObject 深入调用 比较繁琐 大佬用法 萌新勿入
*       2-5:如何关闭 信号与槽 的连接
*   3-信号可以连接信号(*触发链式反应),但是槽不可以连接槽因为没有触发者。 信号和槽的关系是 多对多关系
*   4-connect 第5个参数 决定信号立即发送到槽 还是等待发送  与线程相关  未实现具体代码
*   5-信号的参数个数 = 槽的参数个数  信号的参数类型顺序 = 槽的参数类型顺序(保证参数一一对应基本不会出错)
*   6-路漫漫其修远兮(如果发现自己写的信号槽连接不执行,请看看是否发射信号了~~~)
*/
#include <QCoreApplication>
#include <QDebug>
#include "xobject.h"
#include "xobject_.h"
struct slot_test01{
    void operator()(QString ){
        qDebug()<<__PRETTY_FUNCTION__;
    }
};
void slot_funt(QString )
{
     qDebug()<<__PRETTY_FUNCTION__;
}
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
#if 0  //1-2的内容
    Xobject* x=new Xobject();
    xobject_* x_=new xobject_();

    //QObject下的静态函数connect
    //1-信号可以触发多个槽函数
    QMetaObject::Connection co =
            QObject::connect(x,SIGNAL(say_a(QString)),x_,SLOT(slot_say_a(QString)));
    QMetaObject::Connection co1 =
            QObject::connect(x,SIGNAL(say_a(QString)),x_,SLOT(slot_say_a(QString)));
    //2-成员函数指针  -弊端是出现重载的槽函数无法正常区分 需要使用函数指针明确类型
    //信号函数say_a与槽函数slot_say_a都是重载函数 1个参数 2个参数
    //函数指针 【  返回值类型 (*函数变量名)(函数参数)=&函数名   】
    void (Xobject::*say_a)(QString)=&Xobject::say_a;  //多注意语法规范 say_a为变量名字
    void (xobject_::*slot_say_a)(QString)=&xobject_::slot_say_a;
    QMetaObject::Connection co2 =
            QObject::connect(x,say_a,x_,slot_say_a);
    //3-Function
    QObject::connect(x,say_a,slot_test01());//调用对象 正常执行
    QObject::connect(x,say_a,slot_funt);    //调用方法 正常执行
    //lambda 深入了解可百度常用玩法   [=](参数)->{函数体}   初学者(比如我)直接套用即可默认引用=
    QObject::connect(x,say_a,[](QString){   //lambda 表达式
        qDebug()<<__PRETTY_FUNCTION__;//打印函数信息
    });
    //4-QMetaObject 深入调用 比较繁琐。上面三种掌握 感觉使用上差不多可以了。

    if(co) //自带重写operator() 返回值是bool类型
    {
        qDebug()<<"ok";
    }else {
        qDebug()<<"false";
    }

    x->fashe("");//触发 发射信号
    //断开 x 和 x_  指定的所有信号
    QObject::disconnect(x,0,x_,0);
    //x->disconnect(x_,0);
    //x->disconnect(x_);
    //断开 x 上的所有信号的所有连接(以下三个函数效果一样)
    //QObject::disconnect(x,0,0,0);
    //x->disconnect(0,0,0);
    //x->disconnect();
    //断开 x 上指定的一个信号的所有连接
    //QObject::disconnect(x,SIGNAL(say_a(QString)),0,0);
    //x->disconnect(SIGNAL(say_a(QString)),0,0);
    //x->disconnect(SIGNAL(say_a(QString)));
    //断开一个具体的指定连接
    //QObject::disconnect(x,SIGNAL(say_a(QString)),x_,SLOT(slot_say_a(QString)));


    x->fashe("");//触发 发射信号

    delete x_;
    delete x;
#endif
#if 0 //3 的内容
    Xobject* x=new Xobject();
    Xobject* x1=new Xobject();
    xobject_* x_=new xobject_();
    //连锁反应
    QObject::connect(x,SIGNAL(say_a(QString)),x1,SIGNAL(say_a(QString)));//信号x触发信号x1
    QObject::connect(x1,SIGNAL(say_a(QString)),x_,SLOT(slot_say_a(QString)));//信号x触发信号x1
    x->fashe("");//触发 发射信号  成功(x->x1->x_)

    delete x;
    delete x1;
    delete x_;
#endif
#if 1 //5 的内容
    Xobject* x=new Xobject();
    xobject_* x_=new xobject_();
    //1-信号的参数个数 = 槽的参数个数  可以
    QObject::connect(x,SIGNAL(say_a(QString)),x_,SLOT(slot_say_a(QString)));
    //2-信号的参数个数 > 槽的参数个数  可以
    QObject::connect(x,SIGNAL(say_a(QString)),x_,SLOT(slot_say_a()));
    //3-信号的参数个数 < 槽的参数个数 这种事 不可以的error
    //QObject::connect(x,SIGNAL(say_a()),x_,SLOT(slot_say_a(QString))); error

    x->fashe("");

    delete x;
    delete x_;
#endif
    return a.exec();
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值