【Qt初识】信号槽(一):核心概念与 connect 的使用
大家好我是Halcyon.平安欢迎文末添加好友交流共同进步目录一、信号和槽概念1.1概述1.2 本质1.3 理解二、信号和槽的使用三、如何知道内置信号与槽有哪些 深入理解 connect3.1 学会使用官方文档3.2 connect参数类型解释目录一、信号和槽概念1.1概述我们之前在讲点击按钮的时候将文本内容切换功能的时候提到过信号和槽然后触发事件发出的通知叫信号就比如点击按钮用来接收信号执行功能的方法执行文本内容切换的方法就叫槽。信号和槽都是 Qt 特有的消息传输机制它能将相互独立的控件关联起来。比如按钮和编辑框本身是两个独立控件点击按钮并不会对编辑框造成任何影响。但我们可以借助信号和槽机制把按钮和编辑框关联在一起实现点击按钮切换编辑框文本内容的效果。1.2 本质信号是由于用户对窗口或者控件进行了某些操作导致窗口或控件产生了某个特定的事件这时Qt对应的窗口类会发出某个信号以此对用户的操作做出反应。因此信号的本质就是事件槽slot就是对信号的响应函数。1.3 理解我们可以简单的举一个例子当你回家的时候看着你的对象不开心你做一点小事她就生气你心里盘算了一下为啥呢从自己的脑海中搜索种种可能心想自己也没干啥坏事啊哦突然你想要了一个你最可能的原因原来是每个月女生都有那么几天这时候就去乖乖的冲了一杯红糖水端给她从我们这个例子中我们可以发现信号源对象信号类型不开心生气方式槽快去冲红糖水通过这个例子我们是不是可以更好的理解这个信号与槽了呢它的执行顺序就是先关联信号槽然后触发这才是基本规则。接下来我们看看如何使用二、信号和槽的使用使用的话我们需要用到一个连接函数顾名思义connect它是由QOBjectQt中内置类的祖宗提供的函数含静态重载且Qt中所提供的类都是有继承关系的为什么因为我们之前讲过的对象树。我们来看看connect()函数原型connect(constQObject*sender,constchar*signal,constQObject*receiver,constchar*method,Qt::ConnectionType typeQt::AutoConnection)sender信号源谁发送的信号signal信号类型如鼠标移动、点击按钮、点击键盘等信号处理方式receiver谁来处理即对应的控件method如何处理也就是我们设定的槽函数type Qt::AutoConnection通常是用来指定关联方式的一般是默认不需要我们自己手动设置我们来看个例子更好的了解一下#includewidget.h#includeui_widget.h#includeQPushButtonWidget::Widget(QWidget*parent):QWidget(parent),ui(newUi::Widget){ui-setupUi(this);QPushButton*pushbuttonnewQPushButton(this);pushbutton-setText(关闭窗口);connect(pushbutton,QPushButton::clicked,this,QWidget::close);}Widget::~Widget(){deleteui;}QPushButton::clicked与QWidget::close我们可以看到系统给了我们两个图标其实这能够更加快速的帮助我们分辨出信号与槽函数如第一张图我所框出来的就是信号有三个类似无线网络的弧度的那个如第二张图我所框出来的就是槽函数锯齿形状先创建出一个按钮控件然后设置文本然后把点击按钮这个信号和槽关闭窗口连接起来。信号源就是我们创建的按钮信号类型就是点击这个按钮处理方式就是关闭窗口。此处的close是QWidget内置的槽函数。三、如何知道内置信号与槽有哪些 深入理解 connect接下来我们来解决两个很容易让初学者产生疑惑的问题3.1 学会使用官方文档我们上面说了我们所实现的关闭窗口的函数close是一个内置函数而且触发信号是点击按钮的clicked那这些我们是如何知道的呢解决这个疑问的核心就是多看官方文档不会的就去查询我们直接在搜索框输入我们想要了解的控件名称然后点击搜索就可以看到如下但是当我们把此界面全部翻看后并没有找到clicked这个信号函数的说明聪明的你想到了Qt中的对象树他们是一层一层的继承关系既然此处没有找到我们去看看它的父类呢父类没有呢那就父类的父类去查找呗然后继续在这个界面进行翻阅果不其然就找到了找到后当我们想要查询详细信息的话直接点击它即可我们用ai解读一下建议自己慢慢解读理解看英语文档那不我们必备技能嘛所以我们可以发现查找信号的时候重点就是关注信号的发送时机——比如进行了某操作就产生了这个信号3.2 connect参数类型解释我们会发现connect参数里面的信号类型与处理方法要求传入的都是const char*指针类型而我们手动传入的明显是函数指针毫无疑问这是不同的指针类型我们可以按住ctrl然后鼠标点击clicked和close就可以跳转到它们的函数定义。我们也发现他们的类型是和const char*明显是不一样的形参要求传入的指针类型与实参指针类型是不同的这种情况在C是绝对不允许出现的因为函数的传参本质就是赋值即根本不会允许两种不同的指针类型去相互赋值那么为什么在Qt中我们运行成功后点击关闭窗口按钮它依然能够成功的连接信号与槽那为什么会出现这种情况呢因为我们知道connect函数是QObject中的成员函数由于Widget继承自QWidget而QWidget继承自QObject类所以我们在Widget中可以使用connect并且我们去找connect也应该在文档中搜索QObject找到然后点击它我们就能跳转到相应的函数介绍。我们会发现如果要想将指针类型转换的话我们需要使用**SIGNAL()**这个宏去修饰第二个参数使用**SLOT()**这个修饰去包第四个参数connect(pushbutton,SIGNAL(clicked()),this,SLOT(close()));经过宏的修饰之后宏会将函数指针的类型转化为cong char*类型进行传参也就是说我们的调用connect不需要指定是位于哪一个类中的成员函数通过宏的修饰就将函数指针的类型转化为了const char*进行传参其实这个官方文档是旧版本Qt的connect函数声明以前的传参方法和现在的传参方法是有区别的而我们从Qt5开始就做了简洁不用再写宏直接给connect提供了重载版本第二个和第四个参数成了泛型参数允许你传入任意类型的指针并且带有一定的参数检查功能如果参数传入的不匹配会自动编译出错如果我们传入的第二个参数的函数指针不是第一个参数指向的类的成员函数或者传入的第四个参数的函数指针不是第三个参数指向的类的成员函数就会发生错误就做了简洁不用再写宏直接给connect提供了重载版本第二个和第四个参数成了泛型参数允许你传入任意类型的指针并且带有一定的参数检查功能如果参数传入的不匹配会自动编译出错如果我们传入的第二个参数的函数指针不是第一个参数指向的类的成员函数或者传入的第四个参数的函数指针不是第三个参数指向的类的成员函数就会发生错误