信号与槽机制
信号和槽机制是qt引以为豪的机制之一,他的本质是观察者模式
当某个事件发生后,发出一个信号(signal),对这个信号感兴趣的对象会是用连接函数(connect),将想要处理的信号和自己的一个函数(solt(槽))进行绑定,总之,当信号发出时,被连接的槽函数会自动被回调
connect函数是用信号与槽机制
connect()函数的几个参数如下
connect(sender,signal,receiver,slot);
参数:
sender:信号的发出者
singnal:信号
receiver:信号的接收者
slot:接收到信号需要执行的任务(槽函数)
系统自带的信号和槽
信号:
clicked();//点击信号
pressed();//按下信号
released();//抬起信号
toggled();//切换信号
槽函数:
下面实现点击按钮关闭窗口
QPushButton * button =new QPushButton("关闭窗口",this);
connect(button,&QPushButton::clicked,this,&Widget::close);
参数接受的是四个指针
信号和槽函数需要写对应作用域下的函数名的地址
自定义信号与槽
1.确定场景
老师打开门,同学停止说话
2.制定自己的信号和槽,添加自己的老师类和学生类
3.在老师类中声明信号(打开门)信号千万不要实现
在teacher.h中声明信号,注意,不要实现
signals:
void opendoor();
4.在同学类中声明槽函数(停止说话)
public slots:
void stopspeak();
实现
Student::Student(QObject *parent) : QObject(parent)
{
}
void Student::stopspeak()
{
std::cout<<"老师来了,停止说话"<<std::endl;
}
运行测试案例
connect(t,&Teacher::opendoor,s,&Student::stopspeak);
t->opendoor();
//结果:老师来了,停止说话
信号和槽函数的重载与传参
在传递信号与槽函数时,如果想要传递参数该怎么办,假设有关于槽函数的重载函数,在connect的时候应该怎么才能制定好具体要走那个重载函数
//Teacher.h
signals:
void opendoor();
void opendoor(std::string );
//Teacher.cpp
//Student.h
public slots:
void stopspeak();
void stopspeak(std::string);
//Student.cpp
void Student::stopspeak()
{
std::cout<<"老师来了,停止说话"<<std::endl;
}
void Student::stopspeak(std::string a)
{
std::cout<<"老师来了,"<<a<<"停止说话"<<std::endl;
}
在main 方法中,需要定义四个函数指针,分别指向着2个槽函数,与两个信号
void (Teacher::*signal)()=&Teacher::opendoor;//函数指针,指向无参的
void (Teacher::*signal_with_args)(std::string)=&Teacher::opendoor;//函数指针,指向有参的
void (Student::*slotss)()=&Student::stopspeak;
void (Student::*slotss_with_args)(std::string)=&Student::stopspeak;
当想要用可以传递参数的槽函数时,就需要用带有参数的函数指针替换掉connect中的指针
connect(t,signal_with_args,s,slotss_with_args);
t->opendoor("clg");
//结果:老师来了,clg停止说话
总结
1.信号的发送者和信号的接收者的基类必须是Qobject(槽函数是全局或者lamba表达式除外)
2.信号和槽函数返回值必须是void,并且信号不需要实现,但是槽函数必须要实现
3.槽函数也是普通的成员函数,会受到类的属性的影响(public,private,protect)
4,信号槽要求信号和槽函数的参数是一至的,(参数列表类型顺序一值),当不一致时,要求槽函数的参数比信号的参数少
5.槽函数是松散耦合的,一个信号可以和多个槽相连,一个槽可以接受多个信号,信号之间可以进行拦截,槽可以被取消链接
(一个对象被delete)
6.信号槽可以是用c++11中的lambda表达式