QT信号与槽的连接方式

一.Qt::AutoConnection
Qt::AutoConnection表示系统自动选择相应的连接方式,如果信号与槽在同一线程,就采用Qt::DirectConnection, 
如果信号与槽不在同一线程,将采用Qt::QueuedConnection的连接方式。    

二.Qt::DirectConnection
 Qt::DirectConnection表示一旦信号产生,立即执行槽函数。   (主线程发送信号给子线程,connect 在子线程中 ,则这个参数要使用  Qt::DirectConnection ,槽函数在子线程中立即执行)

三.Qt::QueuedConnection
 Qt::QueuedConnection表示信号产生后,将发送Event给你的receiver所在的线程,postEvent(QEvent::MetaCall,...), 
slot函数会在receiver所在的线程的event loop中进行处理。

四. Qt::BlockingQueuedConnection
 Qt::BlockingQueuedConnection表示信号产生后调用sendEvent(QEvent::MetaCall,...), 
在receiver所在的线程处理完成后才会返回;只能当sender,receiver不在同一线程时才可以。  

五.   Qt::UniqueConnection
 Qt::UniqueConnection表示只有它不是一个重复连接,连接才会成功。如果之前已经有了一个链接(相同的信号连接到同一对象的同一个槽上),那么连接将会失败并将返回false。    
 Qt::AutoCompatConnection与QT3保持兼容性    
 说明一下,对于任何的QThread来说,其线程只存在于run()函数内,其它的函数都不在线程内,所以此处要采用Qt::BlockingQueuedConnection,    
 因为当SOCKET有数据到达时就会发出readyRead()信号,但是此时可能之前的receiveFile()还未执行完毕,之前使用的Qt::AutoConnection,    
 结果传输大文件的时候就会出错,原因就在于只要有数据到达的时候,就会连接信号,但是数据接收还没处理完毕,而Qt::BlockingQueuedConnection会阻塞    
 此连接,直到receiveFile()处理完毕并返回后才发送信号。 
qDebug()<<"run thread:"<<QThread::currentThreadId();  
    connect(tcpSocket,SIGNAL(readyRead()),this,SIGNAL(receiveSgl(tcpSocket))); 
   connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(receiveFile()),Qt::BlockingQueuedConnection); 
    exec(); 
 

Qt 中,信号是一种用于对象间通信的核心机制,它允许对象之间以松耦合的方式进行交互。信号连接方式主要通过 `connect` 函数的第五个参数指定,该参数决定了信号之间如何进行通信。以下是 Qt 中支持的五种主要连接方式及其行为和适用场景: ### 1. 自动连接(`Qt::AutoConnection`) 这是 Qt 的默认连接方式。它会根据信号所属对象所处的线程自动选择连接方式: - 如果信号在同一个线程中,则使用 `Qt::DirectConnection`。 - 如果信号在不同的线程中,则使用 `Qt::QueuedConnection`。 这种方式适用于大多数情况,因为它能根据运行时环境自动选择合适的连接方式,从而简化开发过程[^4]。 ### 2. 直接连接(`Qt::DirectConnection`) 在这种连接方式下,信号发出后会立即调用对应的函数,且函数在信号发出者的线程中执行: - 信号的调用顺序代码顺序一致,即同步调用。 - 适用于信号在同一个线程的情况,或者希望确保信号发出后立即执行函数的场景。 - 如果信号位于不同的线程,使用此连接方式可能会引发并发问题,因此需要特别小心[^4]。 ### 3. 队列连接(`Qt::QueuedConnection`) 在这种连接方式下,信号发出后,函数的调用会被放入接收者线程的事件队列中,函数会在接收者线程空闲时执行: - 信号的调用是异步的,即信号发出后立即返回,函数的执行由事件循环调度。 - 适用于信号在不同线程的情况,能确保信号调用的线程安全性。 - 也适用于希望异步执行函数的场景[^4]。 ### 4. 阻塞队列连接(`Qt::BlockingQueuedConnection`) 这是队列连接的一种特殊形式,信号发出后将函数调用放入接收者线程的事件队列中,并阻塞信号发出线程,直到函数执行完毕: - 信号发出方会被阻塞,直到函数在接收者线程中执行完毕。 - 仅在信号不在同一个线程中时可用,常用于需要线程同步的场景。 - 如果信号在同一个线程中使用此连接方式,程序可能会死锁,因此使用时需谨慎[^4]。 ### 5. 唯一连接(`Qt::UniqueConnection`) 这种连接方式确保相同的信号之间只能建立一次连接: - 如果尝试重复连接同一个信号,将不会建立新的连接。 - 通常 `Qt::AutoConnection` 一起使用,即 `Qt::AutoConnection | Qt::UniqueConnection`。 - 适用于防止重复连接引发的逻辑错误或资源浪费情况,例如在某些条件下信号可能会多次连接同一函数,使用唯一连接可以避免多次执行相同的函数[^4]。 --- ### 使用方式 在 Qt 中,信号的连接通常通过 `connect` 函数实现,其基本语法如下: ```cpp connect(sender, &Sender::signalName, receiver, &Receiver::slotName, connectionType); ``` 其中,`sender` 是发出信号的对象,`receiver` 是接收信号并执行函数的对象,`signalName` 是信号名称,`slotName` 是函数名称,`connectionType` 是连接方式。 以下是一个示例: ```cpp // 假设有两个 QObject 派生类对象 senderObj 和 receiverObj connect(senderObj, &Sender::mySignal, receiverObj, &Receiver::mySlot, Qt::QueuedConnection); ``` 该示例中,`mySignal` 信号被连接到 `mySlot` 函数,并使用 `Qt::QueuedConnection` 连接方式,确保函数在接收者线程中异步执行。 --- ### 信号的线程安全性 在多线程环境下,信号连接方式对线程安全至关重要。`Qt::QueuedConnection` 和 `Qt::BlockingQueuedConnection` 是线程安全的连接方式,而 `Qt::DirectConnection` 则可能引发竞态条件。因此,在跨线程通信时,应优先考虑使用队列连接方式。 --- ### 总结 Qt 提供了多种信号连接方式,开发者可以根据具体需求选择合适的连接类型。例如: - 使用 `Qt::AutoConnection` 简化开发,让 Qt 自动选择连接方式。 - 使用 `Qt::DirectConnection` 实现同步调用。 - 使用 `Qt::QueuedConnection` 实现异步调用和线程安全。 - 使用 `Qt::BlockingQueuedConnection` 实现跨线程同步。 - 使用 `Qt::UniqueConnection` 防止重复连接。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值