Qt 中信号槽的连接方式,即: QObject::connect()
函数的第五个参数 Qt::ConnectionType
,共有五种连接方式。 它决定了是否立刻将特定的信号传递给槽函数,还是将其放在队列中,稍后进行传递。
1. Qt::AutoConnection
:自动连接(默认方式)
当第五个参数缺省时默认为该连接方式。具体为:当接收者和发送者位于同一个线程时,等于Qt::DirectConnection
;当接收者和发送者位于不同的线程时,等于Qt::QueuedConnection
。选择哪一种取决于信号何时被触发。
2. Qt::DirectConnection
:直接连接
该方式表示,当信号被触发时,槽函数立刻被调用。 信号的发送和槽函数的执行位于同一个线程中。
3. Qt::QueuedConnection
:队列连接
该方式表示:当控制权回到接收者所在线程的事件循环时,槽函数才会被调用。槽函数在接收者所在的线程中执行。在这个过程中信号的发送者和接受者不在同一个线程中,所以发送的信号要先存放于队列中,等到控制权回到接收者所在的线程时,才会在该线程中来执行对应的槽函数。
4. Qt::BlockingQueuedConnection
:阻塞连接
该方式与 Qt::QueuedConnection
相同,唯一不同的地方是:发送信号的线程会阻塞,来等待对应的槽函数执行结束,直到槽函数返回,才会继续往下执行。当信号的发送者和接受者位于同一个线程时,禁止使用该连接方式,否则程序会出现死锁。
该连接的一个使用场景是,当需要通过一个GUI程序来启动另一个窗口时,可以先判断当前的线程是否为主线程(即 GUI线程),如果当前线程为GUI线程中,则可以直接像调用普通函数一样来调用对应的槽函数,否则需要通过信号槽的方式来触发对应的信号,等待槽函数在另一个线程中来执行。
QObject::connect(this, &MyObj::SigInfo, this, &MyObj::SlotFunc, Qt::BlockingQueuedConnection);
if(QThread::currentThread() == qApp->thread())
{
// 当信号在主线程中被触发时,直接调用槽函数
this->SlotFunc();
}
else
{
// 当触发信号的时机和槽函数的执行不在一个线程中时,需要通过信号槽的方式来进行触发。
emit SigInfo();
}
5. Qt::UniqueConnection
:唯一连接
该方式表示:信号的发送者和接收者之间只能建立一个连接,如果信号的发送者和接受者之间已经建立了连接,则后续针对该发送者和接收者的任何连接 QObject::connect()
将会失败。且该方式可以和以上四种连接方式的任意一种通过 位或('|') 进行组合使用。