3.1 自定义信号与槽发生重载解决
3.11 实现
给老师类函数写一个带有参数的重载版本:老师发出考试开始信号并警告不要作弊
teacher.h和student.h中分别为
void start(QString cheat);
void starttest(QString cheat);
然后在student.cpp实现
void Student::starttest(QString cheat){
qDebug()<<"不可以:"<<cheat;
}
窗口实现中考试时间开始函数为
void Widget::timeisstart(){
//emit为触发信号的关键字
emit tc->start("作弊");
}
在用之前的连接函数调用考试时间开始函数的时候发现编译错误,这是因为信号和槽的地址中
无法区分带参地址和不带参地址,编译器不知道找哪一个地址
//编译错误
connect(tc,&Teacher::start,st,&Student::starttest);
分析:首先,参数&Teacher::start这是一个函数地址,由函数指针指向函数地址
解决:声明函数指针,再作为connect连接函数的参数,这样就能区分带参地址
返回值为void,先对成员函数的函数地址声明,注意要把成员函数的作用域(Teacher/Student)放到指针前,说明这是teacher作用域下的函数指针,并不是全局函数
//连接带参数的 信号与槽
void (Teacher::*teacherSiggnal)(QString)=&Teacher::start;
void (Student::*studenSlot)(QString)=&Student::starttest;
connect(tc,teacherSiggnal,st,studenSlot);
运行之后发现不能作弊的信号处理能实现出来了,但是发现一个问题,作弊加了引号,但是在student.cpp实现中我们并没有给cheat加有,那么如何解决这个问题呢?
我们在打印“不要:”字符数组类型(char*)双引号没有打印出来,而QString类型打印了,我们是否可以把QString类型转化为字符数组类型呢,答案是可以
转换分为两步,第一步QString参数调用.toUtf8()函数转为QByteArray类型,再调用data()函数转为char*(功能可以在帮助手册上找到)
void Student::starttest(QString cheat){
qDebug()<<"不可以:"<<cheat.toUtf8().data();
}
运行结果为
3.12 按钮点击触发信号
思考:考试时间开始后学生答题,这是我们在运行后就实现的,那么可不可以运行之后设置一个开关让考试时间到,再让学生处理信号呢,我们学习了按钮的操作,可以来试试点击一个考试时间到的按钮,再触发时间到,代码如下
QPushButton*btn=new QPushButton("考试时间到",this);
resize(600,500);
//点击按钮,触发考试时间到
//this指向窗口的指针
connect(btn,&QPushButton::clicked,this,&Widget::timeisstart);
运行结果为,一点击按钮,就触发“考试考试,不可以:作弊”,一直点击可以一直触发。
这里我们连接函数连接的是信号与槽的连接,让槽函数直接处理,其实还可以让信号与信号连接,再让中间信号连接槽函数,信号->信号-槽函数。
3.2 信号连接信号
先让无参信号与槽连接,再让信号连接信号,实现效果是一样的,只不过方式不同。优点可能是代码方便些,不用调用考试开始时间到函数。
//无参信号与槽连接
void (Teacher::*teacherSiggnal2)(void)=&Teacher::start;
void (Student::*studenSlot2)(void)=&Student::starttest;
connect(tc,teacherSiggnal2,st,studenSlot2);
//信号连接信号
connect(btn,&QPushButton::clicked,tc,teacherSiggnal2);
//按钮信号连接了老师下达考试时间到的信号
实现效果为
3.3 断开信号
断开信号的函数为disconnect,参数即为connect连接函数里面的参数,需要断开这个信号,参数复制过来即可。