1、概述
信号槽是Qt框架引以为豪的机制之一。所谓信号槽,实际就是调用回调函数。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,意思是,将想要处理的信号和自己的一个函数(称为槽(slot))绑定来处理这个信号。也就是说,当信号发出时,被连接的槽函数会自动被回调。
使用信号槽的对象需要具备两个条件:
- 通信的对象必须继承自QObject
- 类中要有Q_OBJECT宏
2、函数原型
QObject类是所有Qt对象的基类,此类中有一个静态成员函数connect,用于连接信号槽之间的因果关系,函数原型如下:
参数1:发射者,通信的对象,此对象是信号槽触发的来源,例如:按钮对象(n.)
参数2:信号函数,使用SIGNAL()包裹,表示发射者触发的效果,例如:点击(v.)
参数3:接收者,通信对象,此对象是执行结果代码的主体(n.)
参数4:槽函数,使用SLOT()包裹,表示接收者要执行的函数(v.)
3、类型
A.系统自带的信号和槽
这是最简单的一种连接方式,因为信号函数和槽函数都在Qt中预设了,只需要通过connect函数“连线”即可。
dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QPushButton>
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget *parent = 0);
~Dialog();
private:
QPushButton* btn;
};
#endif // DIALOG_H
dialog.cpp
#include "dialog.h"
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
resize(300,300);
btn = new QPushButton("关闭",this);
btn->move(100,100);
// 参数1,按钮对象 btn
// 参数2,点击函数 void clicked()
// 参数3,窗口对象 this
// 参数4:关闭函数 bool close()
connect(btn,SIGNAL(clicked()),this,SLOT(close()));
}
Dialog::~Dialog()
{
delete btn;
}
B.自定义信号和槽
1.自带信号 → 自定义槽
eg:点击按钮,左下角移动窗口并输出移动后的窗口坐标。
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QPushButton>
#include <QDebug>
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget *parent = 0);
~Dialog();
private:
QPushButton* btn;
// 私有槽函数
private slots:
// 声明自定义槽函数
void mySlot();
};
#endif // DIALOG_H
#include "dialog.h"
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
resize(300,300);
btn = new QPushButton("移动并输出",this);
btn->move(100,100);
// 连接信号槽
connect(btn,SIGNAL(clicked()),this,SLOT(mySlot()));
}
void Dialog::mySlot()
{
// 获得当前坐标
int x = this->x();
int y = this->y();
// 移动窗口
move(x+10,y+10);
// 输出
qDebug() << x << y;
}
Dialog::~Dialog()
{
delete btn;
}
2.自定义信号
信号函数是非常特殊的一种函数,只有声明,没有定义,且不能在代码中直接调用,可以配合emit关键字进行发射。
eg:点击按钮,关闭窗口
dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QPushButton>
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget *parent = 0);
~Dialog();
private:
QPushButton *btn;
// 自定义槽函数
private slots:
void mySlot();
// 声明信号函数,只声明
signals:
void mySignal();
};
#endif // DIALOG_H
dialog.cpp
#include "dialog.h"
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
resize(500,500);
btn = new QPushButton("关闭",this);
btn->move(200,300);
connect(btn,SIGNAL(clicked()),this,SLOT(mySlot()));
connect(this,SIGNAL(mySignal()),this,SLOT(close()));
}
// 自定义槽函数
void Dialog::mySlot()
{
// 发射自定义信号
emit mySignal();
}
Dialog::~Dialog()
{
delete btn;
}