一、连接方式介绍

QMetaObject::Connection QObject::connect(const QObject * sender, const char * signal, 
const QObject * receiver, const char *method,
Qt::ConnectionType type = Qt::AutoConnection)
  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 necessarilythe 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.
    内部通过postEvent实现的。当信号发出后,排队到信号队列中,需等到接收对象所属线程的事件循环取得控制权时才取得该信号,调用相应的槽函数。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.
    内部通过信号量+postEvent实现的。插槽作为队列连接调用,除非当前线程阻塞,直到插槽返回。使用此类型连接同一线程中的对象将导致死锁。
  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 runningin the receiver’s thread, for the same reason that calling any function on an object living in another thread is unsafe.
    该行为与自动连接相同,如果当前信号和槽已经连接过了,就不再连接了。
    请注意,如果事件循环在接收方的线程中运行,那么当发送方和接收方位于不同线程中时使用直接连接是不安全的,这与调用于另一个线程中的对象上的任何函数都是不安全的道理是一样的。
// Qt4连接方式,信号发送者,信号,信号接受者,处理函数
QObject::connect(ui->pushButton,SIGNAL(clicked(bool)),this,SLOT(qT4_slot()));


// Qt5的新方法,编译会有安全监测
QObject::connect(ui->pushButton,&QPushButton::clicked,this,&Widget::qT5_slot);


// Qt5 Lambda表达式,这里需要注意 Lambda表达式是C++ 11 的内容,
// 所以,需要再Pro项目文件中加入 CONFIG += C++ 11
QObject::connect(ui->pushButton,&QPushButton::clicked,[=](){qDebug()<<"lambda 表达式";});

扩展:
1、​​​Qt原理-窥探信号槽的实现细节​​​

2、Qt信号槽-原理分析
3、​​​Qt高级——Qt信号槽机制源码解析​

4、​​Qt实用技能4-认清信号槽的本质​

​ 5、Qt信号与槽传递自定义数据类型——两种解决方法