一、信号与槽是什么?
1.信号和槽是一种通信机制,用于Qt对象之间的通信。是Qt的核心特性。
说明:信号和槽这种通信功能,是由QObject这个类提供的,所以,我们把QObject类及它的派生类对象,称为Qt对象。
信号:是一个函数,当一个Qt对象的内部状态发生改变时,就可以发出一个信号。
槽:是一个函数,当其它Qt对象收到这个信号后,就可以执行。
2.信号和槽的连接:Qobject提供了一个函数connect,用于连接两个Qt对象的信号和槽。
3.对于Qt通信需要了解如下信息:
(1)哪个对象发出信号
(2)发出什么信号
(3)哪个对象接收信号
(4)收到信号后做什么
所以,connect函数的常规参数如下:
connect(发出信号的对象的地址,SIGNAL(信号名称),接收信号的对象的地址,SLOT(槽函数名()));
所有的Qt对象,都有预定义信号和槽,如果预定义的信号与槽功能不能满足需求可以自定义信号和槽。
例如:按钮最常用的信号叫clicked();按钮比较常用的槽函数有show()/hide()/setText()......
界面常用的槽函数,有show()/hide()/close()......
如果需要点击某个按钮时,关闭某个界面,我们只需要把按钮的点击信号与界面的关闭函数连接起来就可以了。例:connect(btn_close,SIGNAL(clicked()),this,SLOT(close()));把关闭按钮和当前界面连接起来后,只要关闭按钮被点击,就会自动发出clicked信号。界面收到信号后,立即自动调用close槽函数。
例:做一个关闭按钮,一点击,则页面关闭
cpp
#include "mydialog.h"
#include "ui_mydialog.h"
MyDialog::MyDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::MyDialog)
{
ui->setupUi(this);
// 连接关闭按钮与当前界面的信号和槽,当按钮的信号发出时clicked,立即自动调用界面的槽函数close
connect(ui->btn_close,SIGNAL(clicked()),this,SLOT(close()));
}
MyDialog::~MyDialog()
{
delete ui;
}
其ui图像如下:
右上角的X代表关闭界面的按钮,一旦点击按钮,则关闭界面。
二、自定义槽函数
1.在头文件中声明
cpp
public/private/protected slots:
返回类型 槽函数名(参数列表);
2.在源文件中定义:返回类型 类名::槽函数名(参数列表) {函数体}
3.使用:
(1)像普通的函数一样直接调用
(2)写在connect函数中与信号相连接,当信号发出来时,自动调用。
例如:利用一个按钮显示或者隐藏日期时间,一开始隐藏,按下按钮之后,显示,再按下按钮之后,隐藏......

按下按钮之后:

修改mainwindow.h文件
cpp
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots://槽函数声明
void onShowOrHidewidget();
private:
Ui::MainWindow *ui;
bool visible;
};
#endif // MAINWINDOW_H
修改mainwindow.cpp文件:
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//初始化可见标志,FALSE表示不可见
visible = false;
//把界面上的日期界面隐藏
ui->widget_time->setVisible(visible);
//连接日期按钮与当前界面类的信号与槽
connect(ui->btn_datetime,SIGNAL(clicked(bool)),this,SLOT(onShowOrHidewidget()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::onShowOrHidewidget()
{
//
//ui->widget_time->hide();
/*if(!this->visible)
{
this->visible=true;
}
else
{
this->visible=false;
}*/
//每次调用槽函数,都修改可见标志的值,如果是真,则修改为假;如果为假,则修改为真。
this->visible=!visible;//或者可以直接取反:
//设置日期界面的可见性
ui->widget_time->setVisible(visible);
}
其ui界面为:

说明:关于connect中的this
例:
connect(ui->btn_datetime,SIGNAL(clicked(bool)),this,SLOT(onShowOrHidewidget()));
ui->btn_datetime,SIGNAL(clicked(bool))即调用界面上按钮(btn_datetime)的成员函数(clicked)
this,SLOT(onShowOrHidewidget())可理解为调用this指向的那个对象的成员函数(onShowOrHideWidget)
connect函数一般是写在构造函数中,构造函数中的this当然就是正在创建的那个对象的地址。比如我们这个例子中,我们用MainWindow类在main函数中创建了一个对象w,即界面对象。简单说,要发信号,得有那个信号,要调用一个槽函数,得有那个槽函数。
三、信号函数
1.默认为公有函数,在声明信号函数时,不需要加public/private/protected
2.自定义信号函数只需要声明,不需要用户添加定义
3.用emit来发送信号
4.信号函数可以传递参数,在connect中连接信号和槽时,如果有参数,只需要写参数类型即可!信号和槽函数的参数要匹配,但是槽函数的参数可以比信号函数的参数少,但不能多。
例:emit 信号函数名(实参列表);
5.信号函数也可以重载、设置默认值。
6.一个信号可以和一个槽相连,一个信号可以和多个槽相连。多个信号可以和一个槽相连。一个信号可以和一个信号相连。
四、自定义信号
signals:
void 信号函数(参数);