目录
Qt坐标系
信号和槽
需求
优点
自定义信号
自定义槽函数
触发自定义信号
代码
main.cpp
widget.h
widget.cpp
teachar.h
teachar.cpp
student.h
student.cpp
结果
重载
解决方法
信号和槽拓展
断开信号和槽
触发多个槽函数
Lambda表达式
[]
()
{}
mutable
返回值
代码
Qt坐标系
从左上角为(0,0)
x:横轴向右
y:竖轴向下
信号和槽
需求
点击按钮,关闭窗口。
/*
* 参数1:信号的发送者
* 参数2:发送的信号
* 参数3:信号的接收者
* 参数4:处理的槽函数
*/
connect(myBtn,&MyButton::clicked,this,&MyWidget::close);
优点
松散耦合。一个事件触发另一个事件。
自定义信号
返回值:void
需要声明,不需要实现
可以有参数
自定义槽函数
返回值:void
需要声明,需要实现
可以有参数
触发自定义信号
emit
代码
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "teachar.h"
#include "student.h"
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
Teachar *zt;
Student *st;
void classIsOver();
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
//需求:创建两个类 Teacher类 Student类
//下课后,老师Teachar zt 发出一个信号 饿了
//学生响应信号Student st 处理信号的槽函数 请客吃饭
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
zt=new Teachar(this);
st=new Student(this);
//连接老师和学生
connect(zt,&Teachar::hungry,st,&Student::treat);
//下课
classIsOver();
}
void Widget::classIsOver(){
//触发老师饿了的信号
//老师饿了的信号属于自定义信号,触发自定义信号关键字emit
emit zt->hungry();
}
Widget::~Widget()
{
}
teachar.h
#ifndef TEACHAR_H
#define TEACHAR_H
#include <QObject>
class Teachar : public QObject
{
Q_OBJECT
public:
explicit Teachar(QObject *parent = nullptr);
signals:
//自定义信号,需要写到signals下
//返回类型,必须是void
//信号只需要声明,不需要实现
//信号可以有参数,可以重载
void hungry();
};
#endif // TEACHAR_H
teachar.cpp
#include "teachar.h"
Teachar::Teachar(QObject *parent) : QObject(parent)
{
}
student.h
#ifndef STUDENT_H
#define STUDENT_H
#include <QObject>
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 <QDebug>
Student::Student(QObject *parent) : QObject(parent)
{
}
void Student::treat(){
qDebug() << "请吃饭";
}
结果
重载
当自定义信号和槽出现重载的时候,原先写法失效,因为执行的函数地址不明确。
解决方法
利用函数指针来明确指向哪个函数的地址。
QString转char *:toUtf8转QByteArray类型,再利用data转成char *。
信号和槽拓展
信号可以连接信号
信号和槽可以断开,disconnect
一个信号可以触发多个槽函数
多个信号可以连接同一个槽函数
信号和槽的参数必须一一对应,参数的个数不一定一一对应。信号的参数个数可以多于槽函数的参数个数,反之不可以,但是必须类型一一对应。
断开信号和槽
disconnect(zt,noTeacharSignal,st,noStSlot);
触发多个槽函数
//触发无参 信号和槽,信号连接信号
void(Teachar::*noTeacharSignal)(void)=&Teachar::hungry;
void(Student::*noStSlot)(void)=&Student::treat;
connect(btn,&QPushButton::clicked,zt,noTeacharSignal);
connect(btn,&QPushButton::clicked,this,&Widget::close);//一个信号可以连接多个槽函数
connect(zt,noTeacharSignal,st,noStSlot);
Lambda表达式
[](){}();
[]
[=]:值传递,推荐
[&]:引用传递,不推荐
()
参数
{}
函数实现体
mutable
改变值传递的内部变量。
返回值
[]()->类型{}();
代码
zt=new Teachar(this);
st=new Student(this);
//连接老师和学生,有参数
void(Teachar::*teacharSignal)(QString)=&Teachar::hungry;
void(Student::*stSlot)(QString)=&Student::treat;
connect(zt,teacharSignal,st,stSlot);
//[=](){}(),用到最频繁
QPushButton *btn2=new QPushButton("aaa",this);
[=](){
btn2->setText("bbb");
btn2->move(100,100);
btn->setText("ccc");
}();
//mutable关键字,用于修改值传递的变量进行修改
QPushButton *myBtn=new QPushButton("myBtn",this);
QPushButton *myBtn2=new QPushButton("myBtn2",this);
myBtn->move(10,10);
myBtn2->move(10,40);
int num=10;
connect(myBtn,&QPushButton::clicked,this,[num]()mutable{num=100+10;qDebug()<<num;});
connect(myBtn2,&QPushButton::clicked,this,[=](){qDebug()<<num;});
qDebug()<<num;
//返回值
int ret=[]()->int{return 10000;}();
qDebug()<<"ret="<<ret;
QPushButton *btn3=new QPushButton("btn3",this);
btn3->move(10,70);
//无参按钮调用有参
connect(btn3,&QPushButton::clicked,this,[=](){
zt->hungry("帝皇蟹");
});
//点击按钮,关闭窗口
connect(btn3,&QPushButton::clicked,this,[=](){
this->close();
});