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();
}