Qt中的信 和槽详解

一、背景介绍

信 和槽用于两个对象之间的通信。信 和槽机制是Qt的核心特征,也是Qt不同于其他开发框架的最突出特征。在GUI编程中,当改变了一个部件时,总希望其他部件也能了解到该变化。更一般来说,我们希望任何对象都可以和其他对象进行通信。例如,用户单击了关闭按钮,则希望可以执行窗口的close()函数来关闭窗口。为了实现对象间的通信,一些工具包中使用了回调(callback)机制,而在Qt中使用了信 和槽来进行对象间的通信。当一个特殊的事情发生时便可以发射一个信 ,比如按钮被单击就发射clicked()信 ;而槽就是一个函数,它在信 发射后被调用来响应这个信 。Qt的部件类中已经定义了一些信 和槽,但是更常用的做法是子类化部件,然后添加自定义的信 和槽来实现想要的功能。

二、Signals and Slots(信 和槽)

信 槽类似于软件设计模式中的观察者模式,(观察者模式是一种对象行为模式。它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。)被观察者发出的信 (signal),观察者收到自己注册监听signal,就通过槽(slot)关联的槽函数function实现动作操作。(这里提一句,Qt 的信 槽使用了额外的处理来实现,并不是 GoF 经典的观察者模式的实现方式)

信 槽优点:

(1)类型安全

信 的参数类型、参数个数需要和槽函数的参数类型和参数个数一致。槽函数的个数也可以少于信 的参数个数,但缺少的参数必须是信 参数的最后一个或最后几个。

(2)松散耦合

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

(3)效率

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

三、实例

下面通过一个简单的例子来进一步讲解信 和槽的相关知识。这个例子实现的效
果是:在主界面中创建一个对话框,在这个对话框中可以输入数值,当单击“OK”按钮
时关闭对话框并且将输入的数值通过信 发射出去,最后在主界面中接收该信 并且
显示数值。程序的运行效果如图所示。

完成后,在ui文件中添加一个pushButton,一个spinBox

在mydialog.h文件中添加代码 

cpp文件

 声明一个信 要使用signals关键字,在signals前面不能用public、private和protected等限定符,因为信 默认是public函数,可以从任何地方进行发射,但是建议只在定义该信 的类及其子类中发射该信 。信 只用声明,不需要也不能对它进行定义实现。

还要注意,信 没有返回值,只能是void类型的。因为只有QObject类及其子类派生的类才能使用信 和槽机制,这里的MyDialog类继承自QDialog类,QDialog类又继承自QWidget类,QWidget类是QObject类的子类,所以这里可以使用信 和槽。不过,使用信 和槽还必须在类声明的最开始处添加Q_OBJECT宏,在这个程序中,类的声明是自动生成的,已经添加了这个宏。

槽就是普通的C++函数,可以像一般的函数一样使用。声明槽要使用slots关键
字,一个槽可以是private、.public或者protected类型的,槽也可以被声明为虚函数,这
与普通的成员函数是一样的。槽的最大特点就是可以和信 关联。
下面打开widget..ui文件,向界面上拖入一个Label部件,更改其文本为“get value is:”。然后进入widget..cpp文件添加头文件#include“mydialog.h”, 

Widget.h文件

cpp文件

现在运行程序查看效果。

这个程序自定义了信 和槽,可以看到它们使用起来很简单,只需要进行关联,然后在适当的时候发射信 即可。这里列举一下使用信 和槽应该注意的几点:

  1. 需要继承自QObject或其子类;
  2. 在类声明的最开始处添加Q OBJECT宏;
  3. 槽中参数的类型要和信 参数的类型相对应,且不能比信 的参数多;
  4. 信 只用声明,没有定义,且返回值为void类型。 

参考:

Qt中的信 和槽详解_徐kun按门铃的博客-CSDN博客_qt 信 槽

Qt的信 槽基本用法总结_夜雨听萧瑟的博客-CSDN博客_qt信 槽

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年8月4日
下一篇 2022年8月4日

相关推荐