使用示例:
QObject::connect(sender, SIGNAL(signal()), receiver, SLOT(slot()), Qt::AutoConnection);
目录
连接方式
一、AutoConnection
二、DirectConnection
三、QueuedConnection
四、BlockingQueuedConnection
五、UniqueConnection
总结
"qnamespace.h"可以看到全部可用连接方式:
enum ConnectionType {
AutoConnection,
DirectConnection,
QueuedConnection,
BlockingQueuedConnection,
UniqueConnection = 0x80
};
顾名思义,最便捷的连接方式,Qt自动根据信号的发送者和槽函数的接受者所处的线程来选择连接方式。
如果处于同一个线程,则自动选择DirectConnection。
如果处于不同线程,则自动选择QueuedConnection。
优点:自动选择,无需手动。
缺点:只是自动选择了连接方式,并不会处理跨线程的参数传递,线程安全都问题,多线程使用时有隐患。
直接调用连接的槽函数而不考虑线程问题。
优点:立即执行。
缺点:因为不考虑线程问题,如果跨线程使用,会出现线程竞争和访问冲突等情况,所以尽量慎用。
信号调用的槽函数会加入队列中,由Qt的事件循环决定,在合适的时间进行处理,会将槽函数的执行推迟。
优点:如果槽函数存在耗时操作,可以将其分离出来,避免出现发出信号的线程阻塞。
如果槽函数在不同的线程中执行,队列方式可以确保槽函数在目标线程中循环执行,避免了线程冲突和并发访问出错。
如果需要按照特定的顺序处理槽函数,该连接方式可以保证槽函数的执行不出现乱序和并发,一定是按照信号的触发顺序执行。
缺点:并非实时的,响应性差。
此方式将槽函数的执行请求放入目标对象所在的线程的事件队列中,等待事件循环处理。在槽函数执行完毕前,发送信号的线程会被阻塞,直到槽函数执行完毕并返回。
优点:跨线程使用,能够忽略线程间的通信和数据同步,并且一定是等待槽函数执行完毕才会释放信号的发送,所以连接者的数据是一致的,对于提高线程安全有很大帮助。
缺点:如果槽函数中存在耗时操作,可能会导致整个界面卡死,处理不当会导致死锁。
唯一连接可以保证连接过程中不会重复连接同一个槽函数。
优点:避免槽函数重复调用或数据重复处理。
缺点:保证的重复只是同一个信号和槽,不同的信号和槽是无法保证的,同时如果不小心重复连接导致Bug,调试时是难以发现问题的。
Qt中信号槽是核心功能,但是一定要正确使用,并且要摒弃文章靠头示例中的老式写法,使用新式写法进行使用,这样在编译阶段就会进行检查,避免调试困难。
connect(myBtn, &QPushButton::clicked, this, &Widget::onClicked);
connect(myBtn, static_cast(&QPushButton::clicked), this, [=](bool check){ //todo});