Qt之信号槽的理解

我们在qt中有太多的地方使用信号槽机制来实现我们功能,但是有没有仔细考虑过信号槽机制的原理呢?有没有问过自己以下几个问题:

  • 信号槽是同步的还是异步的,是阻塞的还是非阻塞的
  • 信号槽如何实现的或者说基于什么来实现的

本篇文章就是视图来解答上面的疑问。好了,进入整体吧,首先介绍一下如何使用信号槽,这个大家都会,但是还是有必须要从头开始说起,使用信号槽需要使用到connect方法,该方法的声明如下:

cpp 复制代码
[static] QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection)

上面的声明中各个参数的介绍如下:

sender:表示的是发送者对象的指针,类型是QObject*

signal:表示的是发送者发送的信号,类型是const char*

receiver:表示的是接受者对象的指针,类型同样是QObject*

method:表示的是接收者的槽函数名称,类型是const char*

AutoConnection:表示的是连接类型,这一个枚举类型,类型是Qt::ConnectionType,枚举值有如下几种:

  • Qt::AutoConnection:该值是默认值,如果调用connect方法时,不指定AutoConnection的值,那么默认使用这个值作为默认值。这个值的含义是如果发送信号的线程和接收对象所在线程为同一个线程,那么AutoConnection=Qt::DirectConnection;否则AutoConnection=Qt::QueuedConnection。注意这里强调的是在那个线程发送对象,而不是说发送对象在那个进程创建的,这里不要混淆了,再说清楚一点就是即使发动对象和接收对象在同一个线程,但是发送信号在别的线程也会AutoConnection=Qt::QueuedConnection。
  • Qt::DirectConnection:该值的含义是槽函数会在信号发送线程中直接调用,即槽函数会在信号发送线程中执行,很明显这是同步调用
  • Qt::QueuedConnection:队列连接,此种连接方式造成的结果是槽函数要在接受者对象所在线程执行。这与DirectConnection连接方式是不同的。并且此种连接方式是通过触发事件循环完成的,即采用此种方式最终是通过postEvent方法将事件发送到接收者对象所在线程的事件队列,进而通过事件队列循环来实现槽函数调用的,从这里可以看出这是一个异步调用
  • Qt::BlockingQueuedConnection:此种连接方式的功能与QueuedConnection基本一致,除一点外就是信号发送后,信号发送线程会阻塞在发信号的语句,待接收者对象所在线程槽函数被执行并返回后,才会继续往下执行。但是需要注意的是若采用此种方式,信号发送线程不能与接收者对象所在线程在同一个线程,否则会导致程序死锁。这里我有一个问题,就是采用这种连接方式槽函数执行结果如何返回给信号发送线程。(这里还是要强调信号发送对象所在线程线程与信号发送线程这二者可能并不一样,这二者不能简单的画等号)。至此可以看出此种连接方式也是异步调用
  • Qt::UniqueConnection:此种连接方式不能单独使用,必须与上面的几种连接方式组合使用,他的含义是确保相同的发送者对象、相同的信号、相同的接受者对象,相同的槽函数只能被绑定一次,否则调用connect方式会失败。
相关推荐
Scott9999HH8 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
码智社9 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海9 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖10 小时前
JDK 26 新特性详解
java·开发语言
马优晨11 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区12 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大13 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai13 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
এ慕ོ冬℘゜13 小时前
前端基础:什么是时间戳?JS获取时间戳三种方法与实战用途
开发语言·前端·javascript
执明wa14 小时前
LayoutInflater详解: XML是如何变成View的?
android·xml·开发语言·android studio