【2017-07-04】Qt信号与槽深入理解之一:信号与槽的连接方式

今天是个好日子,嗯。

信号槽机制是Qt的特色功能之一,类似于windows中的消息机制,在不同的类对象间传递消息时我们经常使用信号槽机制,然而很多时候都没有去关注connect()函数到底有几种重载的形式,其中的各项参数都是什么。

如果总是浮于表面,仅仅是满足于功能实现,而不去深究有哪些可能影响程序行为的参数,或者是作为一种GUI开发框架,她实现这种机制的原理是什么的话,一则是可能得不到提高,二则是在面试的时候问及这些问题时往往只能给出一个模糊的答案。

因此,在接下来的几篇文章中,从最常用的connect参数选择上开始,对Qt的信号槽机制及其实现原理做一次比较深入的梳理。

我们最常用的connect()函数的原型之一如下:

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

最后的ConnectionType是一个缺省的参数,默认为自动连接方式,我们来看一下这个参数有哪些值:

1. AutoConnection

自动连接,默认值。

If the signal is emitted in the thread which the receiving object has affinity then the behavior is the same as the Direct Connection.

Otherwise, the behavior is the same as the Queued Connection.

如果信号的发送者和信号的接受者的对象同属一个线程,那个工作方式与直连方式相同;否则工作方式与排队方式相同。

2. Direct Connection

直接连接。

The slot is invoked immediately, when the signal is emitted. The slot is executed in the emitter's thread, which is not necessarily the receiver's thread.

当信号发出后,相应的槽函数将立即被调用;

emit语句后的代码将在所有槽函数执行完毕后被执行,信号与槽函数关系类似于函数调用,同步执行。

3. Queued Connection

排队方式连接。

The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread.

当信号发出后,排队到信号队列中,需等到接收对象所属线程的事件循环取得控制权时才取得该信号,调用相应的槽函数。

emit语句后的代码将在发出信号后立即被执行,无需等待槽函数执行完毕;

此时信号被塞到信号队列里了,信号与槽函数关系类似于消息通信,异步执行。

4. Blocking Queued Connection

阻塞的排队方式。

The slot is invoked as for the Queued Connection, except the current thread blocks until the slot returns.

Using this type to connect objects in the same thread will cause deadlock.

5. Unique Connection

The behavior is the same as the Auto Connection, but the connection is made only if it does not duplicate an existing connection. 

Be aware that using direct connections when the sender and receiver live in different threads is unsafe if an event loop is running in the receiver's thread, for the same reason that calling any function on an object living in another thread is unsafe.

即跨线程调用QObject是线程不安全的。

但这个怎么理解呢?

posted @ 2017-07-04 17:06  waitingdeng  阅读(7624)  评论(0编辑  收藏  举报