【Qt】信号和槽机制
文章目录
前言
本篇文章将讲到.pro文件,main函数中的相关代码,以及按钮,信号和槽的机制,以及Lambda表达式
一、.pro文件
在使用Qt向导生成的应用程序.pro文件格式如下:
二、main函数中
QApplication a 应用程序对象 在Qt中 有且仅有一个
Widget w 窗口对象
w.show() 函数显示窗口
return a.exec()进入消息循环机制,阻塞功能
三、第一个Qt小程序
按钮的创建
cpp
MWidget::MWidget(QWidget *parent)
: QWidget(parent)
{
//按钮
QPushButton *btn = new QPushButton;
//设置父亲
btn->setParent(this);
//设置文字
btn->setText("古娜拉黑暗之神");
//移动位置
btn->move(100,100);
//第二种创建
QPushButton * btn2 = new QPushButton("巴啦啦能量",this);
//重新指定窗口大小
this->resize(600,400);
//设置窗口标题
this->setWindowTitle("第一个项目");
//限制窗口大小
this->setFixedSize(600,400);
}
上面代码中,一个按钮其实就是一个QPushButton类下的对象,如果只是创建出对象,是无法显示到窗口中的,所以我们需要依赖一个父窗口,也就是指定一个父亲利用setParent函数即可,如果想设置按钮上显示的文字利用setText,移动按钮位置用move
对于窗口而言,我们可以修改左上角窗口的标题setWindowTitle,重新指定窗口大小:resize,或者设置固定的窗口大小setFixedSize;
运行结果
对象模型(对象树)
Qt窗口坐标体系坐标体系:
以左上角为原点(0,0),X向右增加,Y向下增加。
四、信号和槽机制
信号槽是 Qt 框架引以为豪的机制之一。所谓信号槽,实际就是观察者模式。当某个事件发生之后 ,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal) 。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣 ,它就会使用连接(connect)函数 ,意思是,将想要处理的信号和自己的一个函数(称为槽(slot))绑定来处理这个信号 。也就是说,当信号发出时,被连接的槽函数会自动被回调。这就类似观察者模式:当发生了感兴趣的事件,某一个操作就会被自动触发。
系统自带的信号和槽下面我们完成一个小功能,上面我们已经学习了按钮的创建,但是还没有体现出按钮的功能,按钮最大的功能也就是点击后触发一些事情,比如我们点击按钮,就把当前的窗口给关闭掉,那么在Qt中,这样的功能如何实现呢?
connect()函数最常用的一般形式:
connect(sender, signal, receiver, slot);
sender:发出信号的对象
signal:发送对象发出的信号
receiver:接收信号的对象
slot:接收对象在接收到信号之后所需要调用的函数(槽函数)
cpp
QPushButton * quitBtn = new QPushButton("关闭窗口",this);
connect(quitBtn,&QPushButton::clicked,this,&MWidget::close);
自定义信号和槽
使用connect()可以让我们连接系统提供的信号和槽。但是,Qt 的信号槽机制并不仅仅是使用系统提供的那部分,还会允许我们自己设计自己的信号和槽。
下面我们看看使用 Qt 的信号槽:
cpp
//首先定义一个学生类和老师类:
//老师类中声明信号 饿了 hungry
signals:
void hungury();
//学生类中声明槽 请客 treat
public slots:
void treat();
//在窗口中声明一个公共方法下课,这个方法的调用会触发老师饿了这个信号,而响应槽函数学生请客
void MyWidget::ClassIsOver()
{
//发送信号
emit teacher->hungury();
}
//学生响应了槽函数,并且打印信息
//自定义槽函数 实现
void Student::eat()
{
qDebug() << "该吃饭了!";
}
//在窗口中连接信号槽
teacher = new Teacher(this);
student = new Student(this);
connect(teacher,&Teacher::hungury,student,&Student::treat);
//并且调用下课函数,测试打印出 "该吃饭了"
//---------------------------------------------------------------------
//自定义的信号 hungry带参数,需要提供重载的自定义信号和 自定义槽
void hungury(QString name); 自定义信号
void treat(QString name ); 自定义槽
//但是由于有两个重名的自定义信号和自定义的槽,直接连接会报错,所以需要利用函数指针来指向函数地址, 然后在做连接
void (Teacher:: * teacherSingal)(QString) = &Teacher::hungury;
void (Student:: * studentSlot)(QString) = &Student::treat;
connect(teacher,teacherSingal,student,studentSlot);
将QString 转为 char *
.toUtf8()转为 QByteArray数据类型
.data() 转为 char * 类型
信号和槽拓展1.信号是可以连接信号
2.可以断开信号和槽 disconnect
3.一个信号可以响应多个槽函数
4.多个信号可以连接同一个槽函数
5.信号和槽函数的参数类型 必须一一对应,信号的参数个数 可以多余槽函数的参数个数,反之不可以 , 参数类型要一一对应
五、Lambda表达式
C++11中的Lambda表达式用于定义并创建匿名的函数对象 ,以简化编程工作。首先看一下Lambda表达式的基本构成:
<>mutable -> type {}组成[]中可以加 = & a &a ... 推荐 使用 =
() 形参列表
{} 实现体
mutable可以修改按值传递进来的拷贝
-> type 代表lambda表达式返回值类型
总结
到这里这篇文章的内容就结束了,谢谢大家的观看,如果有好的建议可以留言喔,谢谢大家啦!