Qt信号和槽机制

一.信号和槽

1.信号(signal):用于在不同的对象之间传递消息。

当某个事件发生时,比如按钮被点击,它就会发出一个信号。这个信号没有特定目的,类似于广播,它只是通知其他对象发生了某个事件。

2.槽(slot):槽是与信号关联的函数,它用于处理信号。当信号被发射时,与之关联的槽函数会自动被调用。

信号和槽之间的联系是通过QObject::connect函数建立的。这个函数用于将一个信号与一个或多个槽函数连接起来,当信号被触发时,相应的槽函数就会被调用。

信号和槽的关联可以是多对多的关系,即一个信号可以连接多个槽函数,而多个信号也可以连接到同一个槽函数。

这就类似观察者模式:当发生了特定的事件,某一个操作就会被自动触发。

3.举例

开关 -> 被按下 -> 灯 -> 亮了

优点:松散耦合,信号发出端和接收端可以毫无关联,如果要关联就用connect函数。

connect (sender,signal,receiver,slot);

参数:信号发出者   信号   信号接收者   执行的任务(槽函数)

QPushButton *button = new QPushButton(“关闭”,this);

this->resize(600,400);

connect (button,&QPushButton::clicked,this,&Widget::close);

信号发出者:button   信号:clicked

信号接收者:this    执行的任务(槽函数): close

4.自定义信号与槽

步骤一:确定场景

老师饿了,学生请客。

步骤二:添加老师类和学生类

步骤三:在老师类中声明信号,在学生类中声明并实现槽函数

①在teacher.h中:void hungry ( );

信号:在signals作用域下写,返回值void,参数可以存在,仅声明不需要实现,可以重载。

②在student.h中:void treat ( );

槽函数:可以写到public或者全局,参数可以存在,需要声明并实现,可以重载。

③在student.cpp中:实现treat函数。

void Student::treat ( ){

qDbug () <<“请吃饭”;

注意:需要包含QDebug头文件。

步骤四:创建对象并触发下课信号

①在widget.h中,写出学生类和老师类的头文件,声明学生和老师对象,声明触发信号的成员函数(public内):

Teacher *tea;

Student *stu;

void ClassOver ( );

②在widget.cpp中,创建学生和老师对象,定义触发信号的成员函数,并调用该函数:

this->tea=new Teacher (this);

this->stu=new Student (this);

connect ( tea,&Teacher::hungry,stu,&Student::treat );

ClassOver ( );

全局:void Widget::ClassOver ( ){

           emit tea->hungry ( );

           }

步骤五:实现点击按钮,打印“请吃饭”

在上述代码基础上,再添加:

方式一:

connect (button,&QPushButton::clicked,this,&Widget::ClassOver);

方式二:(信号连接信号)

connect (button,&QPushButton::clicked,tea,&Teacher::hungry);

5.重载自定义信号与槽

步骤一:信号声明(带参数)

步骤二:槽函数声明及定义(带参数)

注意:ClassOver函数内容也要带上参数

步骤三:由于函数的重载,所以需要利用函数指针指向函数地址,然后再做连接:

void (Teacher:: *teachersignal) (QString) =&Teacher::hungry;

void (Student:: *studentslot) (QString) =&Student::treat;

connect (tea,teachersignal,stu,studentslot);

步骤四:实现点击按钮,打印“请吃饭 food”,添加上述步骤五方式一中的代码即可。

6.自定义信号槽注意事项:

①发送者与接收者需要是QObject的子类(槽函数全局,lambda除外)。

②槽函数是普通的成员函数,会受到public,private,protected的影响。

③任何成员函数、static函数、全局函数和lambda表达式都可以作为槽函数。

④使用emit在恰当位置发送信号,用connect函数连接信号和槽。

⑤槽函数的参数可以比信号少。

⑥槽可以被断开连接(disconnect),也可以被取消连接(当一个对象被delete则取消这个对象上的槽)。

 

二.Lambda表达式

C++11中的lambda表达式用于定义并创建匿名的函数对象,以简化编程工作。

[capture](parameters)mutable -> return-type{statement}

[capture]:捕获列表,捕获的是那些到定义lambda为止时lambda所在作用范围内可见的局部变量。

(parameters):参数列表,与普通函数的参数列表一致。

mutable:可修改标识符,按值传递函数对象参数时(默认是仅读权限),加上mutable修饰符后,可以修改按值传递进来的拷贝。

return-type:返回值类型。

statement:函数体,内容跟普通函数一致。

注意:

① [ ] 是一个lambda的开始,不能省略。

空:没有使用任何函数对象参数

=:函数体内可以使用lambda所在作用范围内所有可见的局部变量,值传递

&:函数体内可以使用lambda所在作用范围内所有可见的局部变量,引用传递

a:将a按值进行传递

&a:将a按引用进行传递

this:函数体内可以使用lambda所在类中的成员变量

② ( ) 参数列表在不需要传参时可以省略。

③如果使用mutable,参数列表不能省略,即使参数为空;mutable修改的是拷贝而不是值本身。

④返回值类型如果不需要可省略。

⑤函数体内可以使用参数列表,也可以使用捕获列表。

1.通过lambda表达式打印内容

auto fun = [ ] ( ){

qDebug( )<<“lambda”;

};

fun ( );

或者:

int c=12;

[=] ( ){

qDebug( )<<“lambda”;

qDebug( )<<c;

}( );

2.测试参数列表和可修改标识符(如果无mutable,m=20 会报错)

int m=10;

auto fun=[m] (int a,int b) mutable{

qDebug( )<<“lambda”;

m=20;

return a+b;

};

qDebug( )<<fun (100,200);

qDebug( )<<m;

打印结果:300  10

3.槽函数一般可用lambda表达式

connect (button,&QPushButton::clicked,this,[ ] ( ){

qDebug( )<<“lambda”;

});

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值