信号和槽函数
- 一、了解信号和槽的概念
- 二、信号和槽的使用
- 2.1、第一种方法
- 2.2、第二种方法
- 2.3、第三种方法
- 2.4、第四种方法
- 2.5、第五种方法
一、了解信号和槽的概念
信号(Signal):就是在特定条件下被发射的事件,比如QPushButton 最常见的信号就是鼠标单击时发射clicked()信号。
槽函数:当我们收到这个信号后,需要有一个函数对信号响应,这个函数就是槽函数,槽函数跟一般的函数用法一样,只不过槽函数可以跟信号进行关联。当信号被发射时,槽函数将会自动执行。
Qt中,信号的三个要素:
信号源:由哪个控件发出的信号。
信号的类型:用户进行不同的操作,就可能触发不同的信号;点击按钮,触发点击信号;在输入框中移动光标,触发移动光标的信号;勾选一个复选框,选择一个下拉框,都会触发出不同的信号。
信号的处理方式:槽 => 函数;Qt中可以使用connect这样的函数,把一个信号和一个槽关联起来,后续只要信号触发了,Qt就会自动执行槽函数。
补充:
所谓的触发信号,一定是先把信号的处理方式都准备好,在触发信号。
所谓的槽函数本质就是一种回调函数(callback)。
还有什么也用到了回调函数?
c语言阶段:
1.实现转移表,降低代码的“圈复杂度”。
2.实现回调效果 => qsort
c++阶段:
1.STL中函数对象/仿函数。
2.lambda表达式。
Linux中:
1.信号处理函数
2.线程的入口函数
3.epoll基于回调机制
二、信号和槽的使用
connect是QObject(所有类的祖先)提供的一个静态成员函数。(Qt中提供的这些类,存在一定的继承关系)
2.1、第一种方法
Qt5写法
connect静态成员函数的格式:
connect(
const QObject *sender, //当前信号是哪个控件发出来的
const char *signal, //信号的类型
const QObject *receiver, //哪个对象负责处理
const char *method, //槽函数(信号如何处理,提供一个成员函数)
Qt::ConnectionType type = Qt::AutoConnection
第一、第二参数不匹配或者第三、第四参数不匹配(2、4参数的函数指针不是1、3参数的成员函数,就会不匹配),就会编译出错。
创建一个按钮,然后使用connect进行信号和槽的连接
点击程序“退出”按钮,点击信号被触发,就会处理槽函数。
connect(button1, &QPushButton::clicked,this,&Widget::close);
推荐使用这种写法,信号名字、槽函数名字写错了,编译器会直接报错。
c++中,不允许使用两种不同的指针类型,相互赋值。
2.2、第二种方法
Qt4写法
这是Qt4的写法,从Qt5开始就不需要写SIGNAL和SLOT宏了,给connect提供了重载版本,第二个参数和第二个参数成了泛型参数,允许我们传入任意类型的函数指针。
connect(button1, SIGNAL(&QPushButton::clicked),this,SLOT(&Widget::close));
2.3、第三种方法
lambda表达式写法
connect(ui->pushButton,&QPushButton::clicked,[=](参数){
//具体代码
this->close();
});
推荐使用,适用于slot代码比较少的逻辑
2.4、第四种方法
牵线法
这种方法就是在ui控件上,点击控件绑定一个槽函数,然后再自己写槽函数逻辑,但是看着比较混乱,不太推荐。
2.5、第五种方法
自动生成法
在ui设计界面里直接点击控件,选择转到槽,再在里面选择槽函数。(通过这个方式,还可以很直观的看到某个控件有哪些槽函数)
1.拖动按钮到窗口,然后右键,转到槽
2.widget.cpp文件的代码为
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QPushButton* button =new QPushButton(this);
button->setText("按钮");
button->move(300,300);
connect(button,&QPushButton::clicked,this,&Widget::handleClikecd);
}
Widget::~Widget()
{
delete ui;
}
void Widget::handleClikecd()
//按下按钮,修改窗口标题
{
this->setWindowTitle("窗口被按下");
}
//退出按钮的槽函数
void Widget::on_pushButton_clicked()
{
this->close();
}
注意:widget.h文件里的声明要与widget.cpp文件里的定义相匹配。
点击退出,程序关闭,点击按钮,窗口标题被修改。
在Qt中除了connect来连接信号槽之外,还可以通过函数名的方式来自动连接。
//void Widget::on_这个部分是按钮的objectName_信号的名字();
void Widget::on_pushButton_clicked();
当符合上述规则之后,Qt就能自动的把信号和槽建立连接。