QT信号与槽机制

1. 信号是较为高级的机制,事件是较为低级的机制。一般情况下,事件来自底层窗口系统,但是也有可能通过QApplication类的 QApplication::sendEvent()和QApplication::postEvent()来手动发送事件。
2. 信号-槽中,信号触发多个槽是没有固定顺序的,会全部触发。(观察者模式)
事件触发的多个处理者是有固定的顺序的,优先级高的决定是否把事件继 续传递下去(通过返回值)。(职责链模式)
3. 都可以用于跨线程环境,只不过信号-槽要采用“队列连接”或“自动连接(默认)”方式,不能采用“直接连接”(类似回调)。
4. QT手册第7章开头指出:使用信号-槽机制与事件机制的一个根本原则是,在使用一个组件时,使用信号;在实现一个组件时,使用事件机制。原因是:事件机制 是更为底层的机制(也就是某些情况下没有相应信号可以接收),例如鼠标在组件上的划过,按下和抬起,在处理这类事件时,可以决定何时发出类似 clicked()的信号。
5. QCoreApplication::postEvent(),可以给任何线程中的任何对象投递一个事件,事件会在那个创建了对象的线程中通过事件循环派 发。事件过滤器在所有线程中也被支持,不过它限定被监视对象与监视对象生存在同一线程中。类似地, QCoreApplication::sendEvent(),仅用于在调用此函数的线程中向目标对象投递事件。


看到了网友toto07 的提问:

我看到过这样的论断:

"signal和slot机制与GUI的事件循环完全没有关系,当所有链接到这个signal的slot执行完成之后,在emit代码行之后的代码才会被执行。"

"当emit一个信号后,只有在所有与之相连的信号或槽返回后,emit才会返回。"

这2句话说的是同一个意思,但它们对吗?

1. 这2句话是不是针对单线程的,或者说是在同一个线程中的信号和槽?

2. 当线程A,B同时向另一个线程C的同一个槽发射信号时,如果线程C没有自己的事件循环,那些发过来的信号会排队吗,还是会丢失? 如果有事件循环情况又如何? 

3. 接上面的问 题2,假设GUI线程是D,线程C的对象存在于D,那C的槽函数是在C中还是在D中被执行的呢?

4. 线程A在向C发射信号后,会向开头那些话所说的,在C的槽返回之后再执行emit之后的信号么?

 

……

 

Constant

Value

Description

Qt::DirectConnection

1

When emitted, the signal is immediately delivered to the slot.

Qt::QueuedConnection

2

When emitted, the signal is queued until the event loop is able to deliver it to the slot.

Qt::BlockingQueuedConnection

4

Same as QueuedConnection, except that the current thread blocks until the slot has been delivered. This connection type should only be used for receivers in a different thread. Note that misuse of this type can lead to dead locks in your application.

Qt::AutoConnection

0

If the signal is emitted from the thread in which the receiving object lives, the slot is invoked directly, as with Qt::DirectConnection; otherwise the signal is queued, as with Qt::QueuedConnection.

Qt支持三种类型的信号-槽连接:
1,直接连接,当signal发射 时,slot立即调用。此slot在发射signal的那个线程中被执行(不一定是接收对象生存的那个线程)
2,队列连接,当控制权回到对象属于的那个线程的事件循环时,slot被调用。此slot在接收对象生存的那个线程中被执行
3,自动连 接(缺省),假如信号发射与接收者在同一个线程中,其行为如直接连接,否则,其行为如队列连接。
连接类型可能通过以向connect()传递参数来指定。注意的是,当发送者与接收者生存 在不同的线程中,而事件循环正运行于接收者的线程中,使用直接连接是不安全的。同样的道理,调用生存在不同的线程中的对象的函数也是不是安全的。 QObject::connect()本身是线程安全的。

这样toto07 的问题就有答案了。

 

通过这种方法Qt实现了跨线程的signal-slot传递,并且这种signal-slot机制的传递是 利用消息队列,所以说是线程安全的。消息队列不可以独立于GUI,第三篇文章中提到的多线程的signal slot是不经过消息队列的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值