【Qt】信号和槽

目录

🌈前言🌈

📁 信号和槽的概念

📁 使用信号和槽

 📂 代码关联信号槽

 📂 Qt Creator自动生成信号槽代码

📁 自定义信号和槽

 📂 自定义槽

 📂 自定义信号

📁 带参数的信号和槽

📁 断开信号槽的连接

📁 lambda表达式定义槽

📁 Qt信号槽的存在的意义

📁 总结


🌈前言🌈

        本期内容主要讲解Qt中重要概念——信号槽。信号槽是一种解决问题的方案,响应用户操作,处理问题。

        本期内容主要围绕如何使用信号槽,信号槽它的优缺点有哪些进行讲解,零基础学会Qt开发中的信号槽。

📁 信号和槽的概念

        Qt中信号的概念与Linux中信号的概念十分类似,如果你有学习过Linux中信号的概念,那么你也就理解了Qt中信号的概念。

【Linux杂货铺】进程信号-CSDN博客

        在Qt中,用户和控件的每次交互过程称为一个事件,每个事件都会发送一个信号。例如“用户点击按钮”是一个事件,会发出“按钮被点击”的信号。

        每个控件都具有接受发送信号的能力,一个控件还能接受多个不同的信号。对于接收到的信号,控件会做出响应动作,做出的响应动作称为槽。

        在Linux中信号是进程间通信机制,进程收到信号后回去执行回调函数。Qt中也是一样,信号和槽是Qt独有的信息传送机制,将相互独立的空间关联起来。

        信号的本质就是一个事件,槽的本质就是一个回调函数。在Qt中信号的呈现形式是函数,某事件发生时,Qt会执行对应的信号函数,通知使用者,信号的发出者是某个实例化的对象。

        每个信号可以用函数表示,成为信号函数;每个槽也可以用函数示,称为槽函数。

        信号和槽函数通常位于某个类中,信号函数用signals关键字修饰槽函数用public slots,protected slots或者private slots修饰(Qt5与上版本可以省略slots)。

        信号函数只需要声明,不需要定义,而槽函数需要定义。

        一般情况下,我们很少使用自定义信号,Qt提供的信号足够应付大部分场景,如果某种特定需要,需要自定义信号,那我们就需要在一个类中声明一个信号函数,但是不需要定义信号函数。

        信号函数的定义是Qt自动在编译程序之前生成的,编写Qt应用程序的程序员无需关注。这种自动生成代码的机制称为元编程。        

📁 使用信号和槽

        Qt中,QObject类提供了一个静态成员函数connec(),该函数专门用来关联指定的信号函数和槽函数。(QObject是Qt内置的父类,Qt提供的需要类都是直接或间接继承QObject,QObject可以理解为是一个祖宗类)

connect(const QObject* sender,
        const char* signal ,
        const QObject* receiver ,
        const char* method ,
        Qt::ConnectionType type = Qt::AutoConnection )

• sender:信号的发送者;

• signal:发送的信号(信号函数);

• receiver:信号的接收者;

• method:接收信号的槽函数;

• type: 用于指定关联方式,默认的关联方式为 Qt::AutoConnection,通常不需要手动设定。

 📂 代码关联信号槽

        下面代码主要实现按下按钮时,窗口会被关闭。

        此时clicked和close都是类中的函数,而不是char*类型,那么为什么能调用connect呢?因为上述connect是文档中的原型,但是文档并没有更新,现在connect可以支持传递函数类型。但是signal必须是sender中的成员函数,method必须是receiver中的成员函数。

        我们也可以使用自定义槽,来改变窗口标题:

 📂 Qt Creator自动生成信号槽代码

        上述代码,改变窗口标题我们可以可以通过设计窗口来完成:

        Qt Creator会自动生产代码,我们我们只需要在函数内完成槽的逻辑即可,不需要关联信号和槽,Qt会自动关联。

        这两种方案都能够将信号和槽关联起来,具体使用哪种方式,看你自己需求。

⾃动⽣成槽函数的名称有⼀定的规则。槽函数的命名规则为:on_XXX_SSS,其中: 
1、以 " on " 开头,中间使⽤下划线连接起来; 
2、" XXX " 表⽰的是对象名(控件的  objectName  属性)。 
3、" SSS " 表⽰的是对应的信号。 
如:" on_pushButton_clicked() " ,pushButton 代表的是对象名,clicked 是对应的信号。
按照这种命名⻛格定义的槽函数, 就会被 Qt ⾃动的和对应的信号进⾏连接.  

📁 自定义信号和槽

 📂 自定义槽

        (1)早期的 Qt 版本要求槽函数必须写到 "public slots" 下,但是现在高级版本的 Qt 允许写到类的"public" 作用域中或者全局下;

        (2)返回值为 void,需要声明,也需要实现;

        (3)可以有参数,可以发送重载;

 📂 自定义信号

        (1)自定义信号函数必须写到 "signals" 下;

        (2)返回值为 void,只需要声明,不需要实现;

        (3)可以有参数,也可以发生重载;

        使用“emit”关键字发送信号,“emit”是一个空的宏,是可选项,没有什么含义,只是为了提醒开发人员。

📁 带参数的信号和槽

        Qt 的信号和槽也⽀持带有参数, 同时也可以⽀持重载。

        此处我们要求, 信号函数的参数列表要和对应连接的槽函数参数列表⼀致。这里的一致是参数类型一致,个数可以不一致,当参数个数不一致时,槽函数的参数小于信号参数的参数,槽函数会按照参数顺序,拿到信号的前N个参数

        通过参数传递可以达到代码复用的效果

        一个槽函数可能会绑定多个信号,如果我们严格要求槽函数与某个信号函数个数一致,意味着信号绑定到槽的要求提高了。

📁 断开信号槽的连接

        使用disconnect断开连接。主动断开往往是因为信号要绑定到一个新的槽上,为了避免同时调用两个槽,而主动断开。

📁 lambda表达式定义槽

        lambda表达式的定义式如下:

[ capture ] ( params ) opt -> ret {
Function body;
}

符号说明
[ ]局部变量捕获列表。Lambda表达式不能访问外部函数体的任何局部变量
[a]在函数体内部使⽤值传递的⽅式访问a变量
[&b]在函数体内部使⽤引⽤传递的⽅式访问b变量
[=]函数外的所有局部变量都通过值传递的⽅式使⽤, 函数体内使⽤的是副本
[&]以引⽤的⽅式使⽤Lambda表达式外部的所有变量
[=, &foo]foo使⽤引⽤⽅式, 其余是值传递的⽅式
[&, foo]foo使⽤值传递⽅式,其余引⽤传递
[this]在函数内部可以使⽤类的成员函数和成员变量,= 和 & 形式也都会默认引⼊

        由于使用引用方式捕获对象会有局部变量释放了而Lambda函数还没有被调用的情况。如果执行Lambda函数,那么引用传递方式捕获进来的局部变量的值不可预知。所以绝大多数场合使用的形式为: [=] () { }。

📁 Qt信号槽的存在的意义

信号和槽的优点:

        1. 高内聚低耦合,信号发送者不需要知道发出的信号被哪个对象的槽函数接收,槽函数也不需要知道哪些信号关联了自己,Qt的信号槽机制保证了信号与槽函数的调用。支持信号槽机制的类或者父类必须继承于 QObject 类。

        2. 可以支持多对多,即一个信号可以有多个槽,一个槽可以有多个信号。

缺点:

        效率较低,与回调函数相比,信号和槽稍微慢⼀些,因为它们提供了更高的灵活性,尽管在实际应用程序中差别不大。通过信号调用的槽函数比直接调用的速度慢约10倍(这是定位信号的接收对象所需的开销;遍历所有关联;编组/解组传递的参数;多线程时,信号可能需要排队),这种调用速度对性能要求不是非常高的场景是可以忽略的,是可以满足绝大部分场景。
 

📁 总结

        以上就是本期内容,主要讲解了Qt中信号和槽的概念,如何使用信号和槽等。

        如果感觉本期内容对你有帮助,欢迎点赞,关注,收藏Thanks♪(・ω・)ノ

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秋刀鱼的滋味@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值