######################################## 信号和槽 ######################################## 信号和槽是 Qt 带来的非常便利的对象间通信机制,实质上是使用观察者模式包装的回调系统。与之类似的还有 Boost\::Signals、libsigc++ 等。 延续自 Qt4 的 *SIGNAL* 和 *SLOT* 这里不提,这里只讲 Qt5 中类型安全的语法。 信号和槽的优缺点: [#signal]_ - 松散耦合 - QT的信号可以对应多个槽(但他们的调用顺序随机),也可以多个槽映射一个信号 - QT的信号槽的建立和解除绑定十分自由 - 信号槽相比回调函数大约有 10 倍的性能损失 - 信号槽的参数限定很多,例如不能带模板类参数,不能出现宏定义等等 - 信号和槽是类型安全的(Qt 5 语法) 上面的内容很容易理解,之所以信号和槽不能带模板类参数是因为信号连接的对象必须是已经实体化的。但是函数模板可以在 connect 中进行实体化,就没什么限制了 信号和槽的性能损失主要来自: [#slot]_ - 需要定位接收信号的对象; - 安全地遍历所有的关联(如一个信号关联多个槽的情况); - 编组/解组传递的参数; - 多线程的时候,信号可能需要排队等待。 .. seealso:: - `Signals & Slots `_ - `qt5中信号和槽的新语法 `_ - `Unix/C++--libsigc++深入理解 `_ - `Boost.Signals vs libsigc++ `_ .. [#signal] `QT面试题 `_ .. [#slot] `Qt面试题整理 `_ 声明信号和槽 **************************************** 信号的声明必须要在类的 *signal* 节中,而且必须使用 moc 对源文件进行处理。槽函数任意。 连接信号和槽 **************************************** 信号和槽的连接需要保证槽函数需要的参数少于信号提供的参数 当信号有重载形式时,有两种方式: .. code-block:: none connect(&client , qOverload(&QLocalSocket::error) , [=]() {}); connect(&client , static_cast(&QLocalSocket::error) , [=]() {}); 多线程中的信号和槽 **************************************** connect 最后一个参数 ConnectionType 有以下几种选择: +--------------------------+-------+--------------------------------------------------------------------------------------------+ | 枚举名 | 值 | 说明 | +==========================+=======+============================================================================================+ | AutoConnection | 0 | 如果接受者与发射信号的线程位于同一个线程,使用 DirectConnection,否则使用 QueuedConnection | +--------------------------+-------+--------------------------------------------------------------------------------------------+ | DirectConnection | 1 | 适用于单线程,槽函数将会在发射信号的线程中被执行 | +--------------------------+-------+--------------------------------------------------------------------------------------------+ | QueuedConnection | 2 | 当时间循环到接受者线程时执行槽函数,槽函数将会在接受者的线程中被执行 | +--------------------------+-------+--------------------------------------------------------------------------------------------+ | BlockingQueuedConnection | 3 | 与 QueuedConnection 类似,但是信号线程会被阻塞至槽函数返回 | +--------------------------+-------+--------------------------------------------------------------------------------------------+ | UniqueConnection | 0x80 | 这是一个与上面相配合的标志位,当连接已经存在时,返回 false | +--------------------------+-------+--------------------------------------------------------------------------------------------+ | SingleShotCOnnection | 0.100 | 同样是标志位,在槽函数执行一次后自动断开信号和槽 | +--------------------------+-------+--------------------------------------------------------------------------------------------+