信号与槽(Signal & Slot)是 Qt 编程的基础,也是 Qt 的一大创新。因为有了信号与槽的编程机制,在 Qt 中处理界面各个组件的交互操作时变得更加直观和简单。
信号(Signal)就是在特定情况下被发射的事件,例如PushButton 最常见的信号就是鼠标单击时发射的 clicked() 信号,一个 ComboBox 最常见的信号是选择的列表项变化时发射的 CurrentIndexChanged() 信号。
GUI 程序设计的主要内容就是对界面上各组件的信号的响应,只需要知道什么情况下发射哪些信号,合理地去响应和处理这些信号就可以了。
槽(Slot)就是对信号响应的函数。槽就是一个函数,与一般的C++函数是一样的,可以定义在类的任何部分(public、private 或 protected),可以具有任何参数,也可以被直接调用。槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。
.cpp
#include "widget.h"
#include "ui_widget.h"
#include "qpushbutton.h"
//Teacher 类
//Student 类
//
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//创建老师对象
this->TE = new Teacher(this);
//创建学生对象
this->ST = new Student(this);
//连接,老师饿了,学生请客
// connect(TE,&Teacher::hungry,ST,&Student::treat);
// //调用下课函数
// ClassOver();
//当有重载时,存在二义性。
//连接带参数的,信号和槽
//指针->地址
//函数指针->函数指针
void(Teacher::*teacherSignal)(QString) = &Teacher::hungry;
void(Student::*studentSlot)(QString) = &Student::treat;
connect(TE,teacherSignal,ST,studentSlot);
//ClassOver();
//点击下课按钮进行响应
QPushButton * btn = new QPushButton("下课",this);
resize(600,400);
//信号发送者 发送的信号(函数地址)信号接受者 处理的槽函数(地址)
//connect(btn,&QPushButton::clicked,this,&Widget::ClassOver);
//无参信号和槽 按钮只可以连接无参的函数
void(Teacher::*teacherSignal2)(void) = &Teacher::hungry;
void(Student::*studentSlot2)(void) = &Student::treat;
connect(TE,teacherSignal2,ST,studentSlot2);
//信号连接信号
connect(btn,&QPushButton::clicked,TE,teacherSignal2);
//拓展
// 1.信号是可以连接信号的
// 2.一个信号可以连接多个槽函数
// 3.多个信号可以连接同一个槽函数
// 4.信号和槽函数的参数必须类型一一对应
// 5.信号的参数个数,可以多于槽函数的参数个数(例:按钮参数是bool,老师饿了对应无参可以成功,对应有参时失败)
//qT4版本以前信号和槽连接方式
//利用Qt4信号槽 连接无参版本
//QT4版本 底层SIGNAL("hungry") SLOT("treat")以字符串进行检测,没有参数检测
//connect(TE,SIGNAL(hungry()),ST,SLOT(treat(QString)));//不符合标准
//Qt4优点,参数直观,缺点,类型不做检测
QPushButton *btn2 = new QPushButton("关闭",this);
btn2->move(100,200);
connect(btn2,QPushButton::clicked,this,[=](){
btn2->setText("成功");
//this->close();
});
}
void Widget::ClassOver()
{
//下课函数,调用后触发老师饿了的信号,
//自定义信号--触发的关键字emit
//emit TE->hungry();
emit TE->hungry("宫保鸡丁");
}
Widget::~Widget()
{
delete ui;
}
.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "teacher.h"
#include "student.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
//声明对象
Teacher * TE;
Student * ST;
void ClassOver();
};
#endif // WIDGET_H