背景:
信号槽是qt很重要的概念,遇到问题帮助没少看。其中就有signals and slots这一章节,说得很到位。
概念琐碎,记录备忘。不对之处望指正。
【qt信号槽-1】槽函数重写问题,qt_metacall和qt_static_metacall
【qt信号槽-3】(QObject::connect: No such slot)的一种解决方法,connect函数qt4/qt5格式,元数据注册
【qt信号槽-4】槽函数不响应不执行的一种原因:ui提升导致重名
【qt信号槽-5】信号槽相关注意事项记录
用途:
信号槽主要用于各种程序之间的通讯。
比如微软的控件的消息事件响应机制,在qt中就是信号槽。消息就是信号,事件就是槽。
比如对象之间的通信,哪怕不在一个线程。它是线程安全的。但我觉得,信号槽本身安全,但用它干的具体事是否安全还得看程序员。
效率:
本质就是函数回调,但比直接调函数慢十倍。
连接:
先不说unique,connect一次就建立一个连接。
可以多对多。亦即:一个信号连多个槽,或者多个信号连一个槽。
槽的执行顺序和连接建立的顺序一样,先连哪个就先执行哪个。
槽执行时机:
因为本质就是函数调用,所以只要不是queue连接方式,就是顺序执行,一emit,就slot。
如果是queue方式,按队列走,涉及事件循环,那得看线程相关的概念。下面贴出以前的博客连接,以便翻阅。
【Qt线程-1】this,volatile,exec(),moveToThread()_qt线程exec
【Qt线程-2】事件循环(QCoreApplication::processEvents,exec)的应用
【Qt线程-3】使用事件循环,信号,stop变量,sleep阻塞,QWaitCondition+QMutex条件变量,退出子线程工作
【Qt线程-4】事件循环嵌套,BlockingQueuedConnection与QWaitCondition比较
【Qt线程-5】生产者&消费者模型应用(多态,子线程控制,协同,事件循环)
【Qt线程-6】获取当前线程id,thread()和currentThreadId(),不是想当然那样,不使用信号槽可能看不出区别
连接方式:
就是connect函数最后一个参数,网上太多文章。以手册为准。
Qt::AutoConnection
自动模式,sender和receiver在同线程就DirectConnection,跨线程就QueuedConnection。
Qt::DirectConnection
直连模式,相当于顺序执行,发完信号紧跟着槽就执行。主要用于sender和receiver在同线程。
Qt::QueuedConnection
队列方式,槽函数执行不一定是在发完信号之后,基于事件循环,按队列走。具体还是看线程相关。
Qt::BlockingQueuedConnection
阻塞队列方式,在队列模式基础上,具备direct方式的特征,顺序执行,唯一不同的就是跨了线程。
Qt::UniqueConnection
唯一连接,跟数据库的unique一样,就是唯一,个人认为是懒人做法,比如不用考虑connect的重复性,方便了编程。
注意事项:
返回值:
信号槽之间可以有返回值,毕竟本质上是函数调用,所以肯定行。当然只能是顺序执行的情况下。队列模式下得不到返回值。网上有很多文章说明用法,但手册明确说明如下:
They can never have return types (i.e. use void).
个人认为,就不要那样用。
还有个invoke字样的函数,目前我还没觉得什么情况下必须用。
插个曲:以前跟着一位很有想法的大哥做程序,使用sqlserver脚本编程时,他说过:“现在的技术有更好的办法,就不要用游标,用了就是错了,肯定有更高效的方法。”我认为,这种自信有一定道理。所谓“存在即合理”的说法不一定对,因为它的存在也许有其它原因,而这个原因也许是遗留问题,而不是最优做法。
直连和阻塞队列:
就是connect第五个参数,direct和blockingqueue方式都是顺序执行。有些时候可以无视,只要线程安全一样用。但我的看法是,一定要遵循qt的思想,不乱用。不该跨线程的代码,不要让它direct方式跨过去,就用blocking。这一点,还是推荐看线程相关。
槽函数重写:
跟moc有关,槽函数重写的时候,默认是从基类开始执行槽函数的,也就是不需要显式调用。
【qt信号槽-1】槽函数重写问题,qt_metacall和qt_static_metacall
自定义参数类型:
需要元数据注册。
【qt信号槽-3】(QObject::connect: No such slot)的一种解决方法,connect函数qt4/qt5格式,元数据注册
界面提升:
ui通过提升方式,发生嵌套时,控件名一样不能重复,否则槽冲突。
【qt信号槽-4】槽函数不响应不执行的一种原因:ui提升导致重名
结束:
其它问题想到可以不断补充。相关可以看其它博客。