前提条件:创建了窗口,窗口内包含按钮
需求:通过按钮关闭窗口
实现:
connet(信号发送者,信号(地址),信号接受者,槽函数(地址))
信号格式: &信号发送者所属类::信号 ,其中信号为系统为信号所属类创建的系统信号
槽函数格式: &信号接受者所属类别::信号接受者处理信号的槽函数,其中槽函数为系统为信号接收者所属类创建的系统信号
#include "mywidget.h"
//(1)引入按钮头文件
#include "QPushButton"
//引入自定义的按钮
#include
//引入打印头文件
#include
myWidget::myWidget(QWidget *parent)
: QWidget(parent)
{
//(2)创建第一个按钮:首先引入头文件
QPushButton *btn=new QPushButton;
//2.1 显示按钮
//2.1.1方法:使用show以顶层的方式弹出窗口或控件(新开辟窗口进行显示)
//btn->show();
//2.1.2 方法:让窗口或控件依赖在父窗口中(mywidget窗口)
btn->setParent(this);
//2.2显示按钮上文本
btn->setText("第一个按钮");
//(3)创建第二个按钮:
//这种方法创建,会按照控件的大小生成窗口,需要重置窗口大小
QPushButton *btn2=new QPushButton("第二个按钮",this);
//移动按钮
btn2->move(100,100);
//重置窗口大小
resize(600,400);
//设置窗口标题
setWindowTitle("第一个窗口");
//设置固定窗口大小
setFixedSize(600,400);
//设置按钮大小
btn->resize(100,50);
//(4)创建自定义按钮的对象
MyPushButton *btn3=new MyPushButton;
btn3->setText("自定义按钮");
btn3->move(100,200);
btn3->setParent(this);//设置到对象树中
//(5)
//需求点击我的按钮,关闭窗口
//参数1:信号发送者(某个组件,如按钮)
//参数2:发送的信号
// (利用系统的信号,可以查看帮助文档。比如信号发送者是按钮,系统为按钮类设计了相关的信号如点击,长按..)
//参数3:信号接受者
//参数4:(信号接受者)处理的槽函数
// (利用系统的槽函数,可以参看帮助文档。比如接受者是窗口,系统为窗口设计了相关的槽函数,如关闭,隐藏..)
connect(btn3,&MyPushButton::clicked,this,&myWidget::close);
connect(btn2,&QPushButton::clicked,this,&QWidget::close);
}
myWidget::~myWidget()
{
//窗口类对象的析构函数
qDebug()<<"窗口对象的析构"<
实现:
connet(信号发送者,信号(地址),信号接受者,槽函数(地址))
信号格式: &信号发送者所属类::信号 ,其中信号为自定义的信号
槽函数格式: &信号接受者所属类别::信号接受者处理信号的槽函数,其中槽函数为自定义信号
详细情况
信号:
teacher.h:
#ifndef TEACHER_H
#define TEACHER_H
#include
class Teacher : public QObject
{
Q_OBJECT
public:
explicit Teacher(QObject *parent = nullptr);
signals:
//自定义信号:需要写到signals下
//返回类型,必须void
//信号只需要声明,不需要实现
//信号可以有参数
void hungry();
};
#endif // TEACHER_H
teacher.cpp:
#include "teacher.h"
Teacher::Teacher(QObject *parent) : QObject(parent)
{
}
#ifndef STUDENT_H
#define STUDENT_H
#include
class Student : public QObject
{
Q_OBJECT
public:
explicit Student(QObject *parent = nullptr);
signals:
public slots:
//自定义槽函数
//高版本可以写到public下,或者全局函数
//槽函数返回值void
//槽函数需要声明,也需要实现
//槽函数也可以有参数,可以发生重载
void treat();
};
#endif // STUDENT_H
student.cpp:
#include "student.h"
#include
Student::Student(QObject *parent) : QObject(parent)
{
}
//槽函数实现
void Student::treat()
{
qDebug()<<"请老师吃饭"<
在窗口中, 使用槽函数和信号:首先创建信号发送者和信号接受者;然后通过connect建立连接;最后使用emit关键字触发信号,信号将通过连接传给信号接受者启动槽函数
widget.h:
#ifndef WIDGET_H
#define WIDGET_H
#include
#include"teacher.h"
#include"student.h"
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
Teacher* zt;
Student* st;
void classIsOver();
};
#endif // WIDGET_H
#include "widget.h"
//需求:创建两个类,Teacher类 Student类
//下课后,老师Teacher zt 会发出一个信号,饿了
//学生响应信号Student st,处理信号的槽函数,请客吃饭
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
zt = new Teacher(this);
st =new Student(this);
//链接老师和学生
connect(zt,&Teacher::hungry,st,&Student::treat);
//下课
classIsOver();
}
void Widget::classIsOver()
{
//触发老师饿了的信号
//老师饿了的信号属于自定义信号,触发自定义信号关键字 emit
emit zt->hungry();
}
Widget::~Widget()
{
}
#ifndef TEACHER_H
#define TEACHER_H
#include
class Teacher : public QObject
{
Q_OBJECT
public:
explicit Teacher(QObject *parent = nullptr);
signals:
//自定义信号:需要写到signals下
//返回类型,必须void
//信号只需要声明,不需要实现
//信号可以有参数
void hungry();
void hungry(QString foodName);
};
#endif // TEACHER_H
#ifndef TEACHER_H
#define TEACHER_H
#include
class Teacher : public QObject
{
Q_OBJECT
public:
explicit Teacher(QObject *parent = nullptr);
signals:
//自定义信号:需要写到signals下
//返回类型,必须void
//信号只需要声明,不需要实现
//信号可以有参数
void hungry();
void hungry(QString foodName);
};
#endif // TEACHER_H
#include "student.h"
#include
Student::Student(QObject *parent) : QObject(parent)
{
}
//槽函数实现
void Student::treat()
{
qDebug()<<"请老师吃饭"<
使用有参的槽函数和信号:
需要明确(重载)信号和(重载)槽函数的地址:例 void (Teacher::*teacherSignal )(QString)=&Teacher::hungry---------》代表参数为QString的重载函数的地址
#include "widget.h"
//需求:创建两个类,Teacher类 Student类
//下课后,老师Teacher zt 会发出一个信号,饿了
//学生响应信号Student st,处理信号的槽函数,请客吃饭
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
zt = new Teacher(this);
st =new Student(this);
//链接老师和学生
//connect(zt,&Teacher::hungry,st,&Student::treat);
//有参数,信号和槽函数
//函数指针,执行函数地址
void(Teacher:: *teacherSignal)(QString)=&Teacher::hungry;
void(Student::* stSlot)(QString)=&Student::treat;
connect(zt,teacherSignal,st,stSlot);
//下课
classIsOver();
}
void Widget::classIsOver()
{
//触发老师饿了的信号
//老师饿了的信号属于自定义信号,触发自定义信号关键字 emit
//emit zt->hungry();
emit zt->hungry("宫爆鸡丁");
}
Widget::~Widget()
{
}
使用无参的槽函数和信号:需要明确(重载)信号和(重载)槽函数的地址:例 void (Teacher::*teacherSignal )(void)=&Teacher::hungry---------》代表无参的函数的地址
代码:connect(信号发送者,无参信号(地址),信号接受者,无参槽函数(地址)
#include "widget.h"
//需求:创建两个类,Teacher类 Student类
//下课后,老师Teacher zt 会发出一个信号,饿了
//学生响应信号Student st,处理信号的槽函数,请客吃饭
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
zt = new Teacher(this);
st =new Student(this);
//链接老师和学生
//connect(zt,&Teacher::hungry,st,&Student::treat);
//有参数,信号和槽函数
//函数指针,执行函数地址
void(Teacher:: *teacherSignal)(QString)=&Teacher::hungry;
void(Student::* stSlot)(QString)=&Student::treat;
connect(zt,teacherSignal,st,stSlot);
//下课
classIsOver();
//无参的槽函数和信号建立连接
void (Teacher::*teacherSignal1 )(void)=&Teacher::hungry;//将无参的信号的地址付给teacherSignal
void (Student ::*studentSlot1 )(void)=&Student::treat;//将无参的槽函数付给studentSlot
connect(zt,teacherSignal1,st,studentSlot1);
//调用下课函数
classIsOver();//调用classisover函数,该函数用于触发老师
//饿了的信号,因为上面信号做了一个连接,所以信号被信号接收者
//接收,然后调用槽函数
}
void Widget::classIsOver()
{
//触发老师饿了的信号
//老师饿了的信号属于自定义信号,触发自定义信号关键字 emit
emit zt->hungry();
//emit zt->hungry("宫爆鸡丁");
}
Widget::~Widget()
{
}
代码:connect(信号发送者,信号(地址),信号接受者,信号(地址))
流程:一个按钮点击信号——>触发第一个连接的信号——>该信号触发另一个连接的槽函数
widget.cpp:
#include "widget.h"
#include
//需求:创建两个类,Teacher类 Student类
//下课后,老师Teacher zt 会发出一个信号,饿了
//学生响应信号Student st,处理信号的槽函数,请客吃饭
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
zt = new Teacher(this);
st =new Student(this);
//链接老师和学生
//connect(zt,&Teacher::hungry,st,&Student::treat);
//有参数,信号和槽函数
//函数指针,执行函数地址
// void(Teacher:: *teacherSignal)(QString)=&Teacher::hungry;
// void(Student::* stSlot)(QString)=&Student::treat;
// connect(zt,teacherSignal,st,stSlot);
// //下课
// classIsOver();
// //无参的槽函数和信号建立连接
// void (Teacher::*teacherSignal1 )(void)=&Teacher::hungry;//将无参的信号的地址付给teacherSignal
// void (Student ::*studentSlot1 )(void)=&Student::treat;//将无参的槽函数付给studentSlot
// connect(zt,teacherSignal1,st,studentSlot1);
// //调用下课函数
// classIsOver();//调用classisover函数,该函数用于触发老师
// //饿了的信号,因为上面信号做了一个连接,所以信号被信号接收者
// //接收,然后调用槽函数
//点击按钮,才下课
QPushButton* btn = new QPushButton("下课",this);
//触发无参信号和槽
//信号连接信号
void (Teacher:: *teacherSignal1 )(void)=&Teacher::hungry;
void (Student :: *studentSlot1 )(void)=&Student::treat;
connect(btn,&QPushButton::clicked,zt,teacherSignal1);
connect(zt,teacherSignal1,st,studentSlot1);
//重置大小
resize(600,400);
}
void Widget::classIsOver()
{
//触发老师饿了的信号
//老师饿了的信号属于自定义信号,触发自定义信号关键字 emit
emit zt->hungry();
//emit zt->hungry("宫爆鸡丁");
}
Widget::~Widget()
{
}
代码:disconnect(信号发送者,信号,信号接受者,信号)
#include "widget.h"
#include
//需求:创建两个类,Teacher类 Student类
//下课后,老师Teacher zt 会发出一个信号,饿了
//学生响应信号Student st,处理信号的槽函数,请客吃饭
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
zt = new Teacher(this);
st =new Student(this);
//链接老师和学生
//connect(zt,&Teacher::hungry,st,&Student::treat);
//有参数,信号和槽函数
//函数指针,执行函数地址
// void(Teacher:: *teacherSignal)(QString)=&Teacher::hungry;
// void(Student::* stSlot)(QString)=&Student::treat;
// connect(zt,teacherSignal,st,stSlot);
// //下课
// classIsOver();
// //无参的槽函数和信号建立连接
// void (Teacher::*teacherSignal1 )(void)=&Teacher::hungry;//将无参的信号的地址付给teacherSignal
// void (Student ::*studentSlot1 )(void)=&Student::treat;//将无参的槽函数付给studentSlot
// connect(zt,teacherSignal1,st,studentSlot1);
// //调用下课函数
// classIsOver();//调用classisover函数,该函数用于触发老师
// //饿了的信号,因为上面信号做了一个连接,所以信号被信号接收者
// //接收,然后调用槽函数
//点击按钮,才下课
QPushButton* btn = new QPushButton("下课",this);
//触发无参信号和槽
//信号连接信号
void (Teacher:: *teacherSignal1 )(void)=&Teacher::hungry;
void (Student :: *studentSlot1 )(void)=&Student::treat;
connect(btn,&QPushButton::clicked,zt,teacherSignal1);
connect(zt,teacherSignal1,st,studentSlot1);
//断开信号和槽
disconnect(zt,teacherSignal1,st,studentSlot1)
//重置大小
resize(600,400);
}
void Widget::classIsOver()
{
//触发老师饿了的信号
//老师饿了的信号属于自定义信号,触发自定义信号关键字 emit
emit zt->hungry();
//emit zt->hungry("宫爆鸡丁");
}
Widget::~Widget()
{
}
(1)信号可以连接信号
(2)信号和槽可以断开 discount
(3)一个信号可以连接多个槽函数
(4)多个信号可以连接一个槽函数
(5)信号和槽函数的参数必须类型一一对应
(6)信号和槽函数的参数个数不需要一致,信号参数个数可以多余槽函数参数个数,并且槽函数的参数与信号的参数类型一致,反之不可以
C++11中,Lambda表达式用于定义并创建匿名函数对象,以简化编程工作。Lambda表达式的基本构成:
[ capture ] ( parameters ) mutable ->return-type { statement };
[ 函数对象参数 ] ( 操作符重载函数参数) mutable ->返回值 { 函数体 };
参数:
(1)函数对象参数[ ]: []标识一个lambda函数的开始,不能省略,函数对象参数是传递给编译器自动生成的函数对象类的构造函数的,函数对象参数只能使用那些定义Lambda为止时Lambda所在作用范围内可见的局部变量(包括Lambda所在类的this),函数对象参数有以下几个形式:
[ ]:没有使用任何函数对象参数
[=]:函数体内可以使用函数所在作用域范围内所有可见的局部变量(包括Lambda所在类的this),并且是值传递方式(相当于编译器自动为我们按值传递了所有局部变量)推荐值传递方式
[&]: 函数体内可以使用函数所在作用域范围内所有可见的局部变量(包括Lambda所在类的this),并且是引用传递方式(相当于编译器自动为我们按引用传递了所有局部变量)推荐值传递
[this]:函数体内,可以使用函数所在类中的成员变量
[a]:将a进行按值传递,并且按值传递时,函数体内不能修改传递进来的a的拷贝,因为默认情况下函数是const的,要修改传递进来的a的拷贝,可以添加mutable修饰符
[&a]:将a进行按引用传递
[=,&a]:除了a按引用,其他都是按值
(2) 操作符重载函数参数(): 标识重载的()操作符的参数,没有参数时,这部分可以省略,参数可以通过按值和按引用两种方式进行传递
(3)mutible可修改标识符: mutible声明,按值传递函数对象时,加上mutable修饰符后,可以修改按值传递进来的拷贝(注意是修改拷贝,不是值本身),否则始终不可修改
(4)返回值类型(函数返回值): 当返回值为void类型时,或者函数体中只有一处return的地方时,这部分可以省略
(5) 函数体 {}: 这部分不可以省略,但是可以为空
#include "widget.h"
#include
#include
//需求:创建两个类,Teacher类 Student类
//下课后,老师Teacher zt 会发出一个信号,饿了
//学生响应信号Student st,处理信号的槽函数,请客吃饭
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
QPushButton *btn1=new QPushButton;
btn1->setParent(this);
btn1->setText("第一个按钮");
QPushButton *btn2=new QPushButton;
btn2->setParent(this);
btn2->setText("第二个按钮");
btn2->move(200,200);
//lambda函数声明
// [=](){
// btn1->setText("改名第一个按钮");
// btn2->setText("改名第二个按钮");
// };
[=](){
btn1->setText("改名第一个按钮");
btn2->setText("改名第二个按钮");
}();
//mutable关键字
QPushButton *btn3=new QPushButton;
btn3->setParent(this);
btn3->setText("按钮1");
btn3->move(300,0);
QPushButton *btn4=new QPushButton;
btn4->setParent(this);
btn4->setText("按钮2");
btn4->move(300,100);
int a=10;
connect(btn3,&QPushButton::clicked,this,
[a]()mutable{a=a+100;qDebug()<返回值类型
int b=[]()->int {return 100;}();
qDebug()<setParent(this);
btn5->setText("lambda案例");
btn5->move(500,200);
//做信号槽函数,默认内部变量会进行锁状态,只读状态,如果进行写操作,就会挂掉
connect(btn5,&QPushButton::clicked,this,[=]()
{
this->close();
//关闭窗口的代码,也可以填入槽函数,或者信号等。。。
});
}
void Widget::classIsOver()
{
//触发老师饿了的信号
//老师饿了的信号属于自定义信号,触发自定义信号关键字 emit
emit zt->hungry();
//emit zt->hungry("宫爆鸡丁");
}
Widget::~Widget()
{
}