QT信号槽

基础使用

  • 信号和槽机制是 Qt 的核心机制,可以让编程人员将互不相关的对象绑定在一起,实现对象之间的通信。
  • 所有从 QObject 或其子类 ( 例如 Qwidget ) 派生的类都能够包含信号和槽。因为信号与槽的连接是通过 QObject 的 connect() 成员函数来实现的。
connect(sender, SIGNAL(signal), receiver, SLOT(slot));
  • 其中 sender 与 receiver 是指向对象的指针,SIGNAL() 与 SLOT() 是转换信号与槽的宏。
  • 一个信号可以连接多个槽,当信号发出时,会以不确定的顺序逐一调用槽函数
  • 信号可以连接信号,第一个信号发出后引起第二信号发出
  • 连接可以移除,因为在对象删除时会自动移除所以较少使用
disconnect(sender, SIGNAL(signal), receiver, SLOT(slot));
  • 如果信号槽连接两次,那么信号发生时,槽函数将调用两次
  • signals前面不可加public、private和protected进行修饰;slots前面可以加,因为Qt说槽函数可以当普通函数使用
  • signals区域的函数必须是void类型,而且这些信号函数没有函数体,也就是说不可以自己定义这些信号函数
  • 宏定义和函数指针不能用于信号和槽的参数,信号和槽也不能有缺省参数

connect函数的第五个参数


注意问题

连接失败

信号槽发送不成功可能是connect连接失败了,connect返回true表示连接成功

  • 信号槽函数的参数类型或参数个数不一致,导致连接会失败
  • 信号槽函数经过SIGNAL() 与 SLOT() 转换宏包裹后再元对象系统中为字符串不会检查错误推荐QT5以上使用新的写法
  • 信号槽函数中消息类型没有注册在元对象系统,此时connect函数也会返回false。可以单步跟踪QT代码。注册消息需要添加类似qRegisterMetaType<QList<CDPSlaBaseInfo>>("QList<CDPSlaBaseInfo>");

跨线程使用

  • QT中跨线程推荐使用信号槽的方式传递信息,如果访问信息速度很频繁数据很大推荐用指针直接访问的方式。
  • 跨线程请指定连接方式Qt::QueuedConnection,调试QT4.8.6时发现跨线程connect默认应该是Auto跨线程也就是Qt::QueuedConnection的连接方式,connect返回成功但信息实际上并没有发送过去!指定Qt::QueuedConnection的连接方式连接后connect返回false,也就是说auto的连接并没有在跨线程中默认为Qt::QueuedConnection,所以最好手动指定。

设计模式思考

  • 信号槽代替了函数指针,用统一的方式实现了回调函数、对象间的消息的传递、跨线程的消息传递,使程序更简洁,是MVC设计模式的通信基础。
  • 但是在有些场景下,这样传递消息是比较麻烦的,而且过多的信号槽连接增加了程序调试的困难,过多的消息传递让MVC代码不够优雅。
  • React/redex前端的单一数据流结构属于发布订阅的设计模式,就很清晰不会漏发消息。
posted @   wuya178  阅读(178)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示