目录
一、概述
在 Qt 中,用户和控件的每次交互过程称为一个事件,而每个事件都会发出一个信号。Qt 中的所有控件都具有接受信号的能力,一个控件可以接收多个不同的信号。对于接收到的每个信号,控件都会做出相应的响应动作。在 Qt 中,对信号做出的响应动作就称之为槽。
信号与槽机制是Qt特有的消息传输机制,它可以将相互独立的控件关联起来。例如可以通过到给按钮绑定关闭窗口的槽函数,通过点击按钮实现关闭窗口的效果。
1、信号的本质
信号是由于用户对窗口或控件进行了某些操作,导致窗口或控件产生了某个特定的事件,这时 Qt 对应的窗口类就会发出某个信号,以此对用户的操作做出反应,执行对应的槽函数。
2、槽的本质
槽就是对信号响应的函数。槽就是⼀个函数,与⼀般的 C++ 函数是⼀样的,可以定义在类的任何位置( public、protected 或 private ),可以具有任何参数,可以被重载,也可以被直接调 ⽤)。槽函数与⼀般的函数不同的是:槽函数可以与⼀个信号关联,当信号被 发射时,关联的槽函数被⾃动执⾏。
二、信号与槽的使用
1、连接信号与槽
connect (const QObject *sender, const char * signal ,const QObject * receiver ,
const char * method , Qt::ConnectionType type = Qt::AutoConnection )
作用:给信号绑定槽函数
参数:
- sender:信号的发送者
- signal:发送哪种信号
- receiver:信号的接收者
- method:接收信号的槽函数
- type:用于指定关联方式,默认的关联方式是 Qt::AutoConnection,通常不需要手动设定。
以下是使用代码生成信号槽代码,达到点击按钮关闭窗口的效果。
2、使用ui设计界面是生成信号槽代码
除了使用代码生成信号槽代码以外,Qt 还支持使用 ui 设计界面来生成对于的信号槽代码。
拖动 PushButton 组件左击编辑组件文本内容,右击选择转到槽并选择 clicked() 信号。
此时 Qt 会自动生成对应的槽函数并绑定链接,用户只需关心槽函数内部的实现即可。
三、自定义信号与槽
在上例中使用 Qt 提供的信号:clicked(),即点击信号。实际 Qt 也支持自定义信号与槽。
1、基本语法
自定义信号:
- 自定义信号函数必须写道 "signals" 下;
- 返回值为 void,只需要声明,不需要实现;
- 可以有参数,也可以进行重载;
自定义槽函数:
- 早期 Qt 版本要求槽函数必须写到 "public slots" 下,但是在高级版本的 Qt 允许写到类的 "public" 作用域或者全局下;
- 返回值为 void,需要声明,也需要实现;
- 可以有参数,可以进行重载;
发送信号:
使⽤ "emit" 关键字发送信号 。
2、案例
给按钮绑定槽函数,在槽函数内实现发送信号,而信号对应的槽函数将窗口名进行修改。
3、携带参数的信号与槽
Qt 的信号与槽也支持带有参数,同时也支持重载。信号函数的参数列表要和对应连接的槽函数参数列表⼀致。但实际信号与槽的参数可以不一致,但是信号的参数一定要比槽函数的操作要多,该机制是用于同一个信号绑定多个槽函数,因此信号的参数一定要比槽函数的要多。
仍采用上例进行说明:由按钮的槽函数发射信号并传入参数。
四、信号与槽的连接方式
信号与槽的连接方式包括一对一,一对多和多对一。
1、一对一
该主要有两种形式,分别是:一个信号连接一个槽和一个信号连接一个信号。一个信号连接一个槽为最基本的使用,这里不进行赘述了。
一个信号连接一个信号:按钮对应的槽函数会触发新的自定义信号,从而执行自定义信号的槽函数。
2、一对多
一个信号可以对应多个槽函数,例如:按钮触发信号后会触发修改窗口标题和移动按钮所处的位置。
3、多对一
多个信号可以绑定同一个槽函数。例如:给俩个按钮绑定同一个槽函数,该函数会打印输出“信号被触发”。
五、相关知识
1、信号与槽的断开
Qt 提供 disconnect 完成信号与槽的断开,使用仿佛与 connect 基本一致。
设置两个按钮,按钮1绑定了一个槽函数,当触发按钮2时会重新为按钮1绑定一个新的槽函数。
2、使用 Lambda 表达式定义槽函数
Qt 5在 Qt 4的基础上提供了信号与槽的灵活性,允许使用任意函数作为槽函数,也就是支持 Lambda 表达式来定义槽函数。