Qt之信号槽的理解


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

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

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

[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方式会失败。

猜你喜欢

转载自blog.csdn.net/iqanchao/article/details/132790959