Qt槽函数不响应的原因总结

Qt专栏:http://t.csdnimg.cn/LE2Lx

目录

1.问题

2.原因

2.1.没有继承QObject,声明Q_OBJECT宏

2.2.信号槽参数不匹配

2.3.信号函数未声明为 signals

2.4.访问权限

2.5.注意connect的位置,信号在创建信号槽连接前使用,则无法触发槽函数

2.6.连接方式为Qt::QueuedConnection时参数类型没有注册

2.7.对象生命周期

2.8.事件循环被阻塞导致信号未能发出

2.9.连接类型

2.10.跨线程

2.11.未定义的行为

3.总结


1.问题

        昨天在调试Qt程序的时候,信号和槽的参数用到了std::uint64_t,当信号发出了,槽函数再怎么都不响应,程序也没有报什么错,这个是为什么呢?过了一会才想起是不是系统没有注册std::uint64_t类型哦,于是在系统初始化的地方增加了:

qRegisterMetaType("std::uint64_t");

 再次调试,槽函数响应了,原来是这个问题。

        其实出现类似槽函数不响应的原因还有一些,今天就列举一下,供大家查阅。

2.原因

2.1.没有继承QObject,声明Q_OBJECT宏

        因为信号槽机制是需要依赖Qt的反射机制的,如果不继承Object,编写信号和槽函数的时候就会直接报错的。

2.2.信号槽参数不匹配

        信号槽的参数必须匹配。如果信号有参数,槽也必须具有相同数量和类型的参数。需要特别指出的是,在参数类型属于某命名空间时,要把命名空间写完整。

2.3.信号函数未声明为 signals

2.4.访问权限

        定义信号signals不需要指定类型,默认就是public的。但是槽函数可以定义为pubic slots或 private slots或 protected slots。有时,私有信号和槽不能被外部对象连接。

2.5.注意connect的位置,信号在创建信号槽连接前使用,则无法触发槽函数

2.6.连接方式为Qt::QueuedConnection时参数类型没有注册

        信号槽的参数是自定义的,这时需要用qRegisterMetaType注册一下这种类型。需要使用

 #include  qRegisterMetaType<此处为变量类型名称>("此处为变量类型名称")

来注册。 在Qt帮助手册中搜索qRegisterMetaType,有相关说明。 注意在调用connect时指定连接方式为Qt::DirectConnection(阻塞式触发),不会存在此问题。因为阻塞式触发,只需要将参数进行值传递,拷贝过去即可。而以Qt::QueuedConnection(消息队列式)连接的情况下,需要将变量转成通用数据类型QVariant存储,而用QVariant存储,必须要注册此类型。

2.7.对象生命周期

        如果尝试连接的对象在连接时已经被销毁,那么连接就不会成功。确保对象在连接期间是有效的。

2.8.事件循环被阻塞导致信号未能发出

2.9.连接类型

        使用适当的连接类型。Qt提供了几种不同的连接类型,包括Qt::DirectConnection、Qt::QueueConnection、Qt::AutoConnection等。

2.10.跨线程

        如果信号和槽跨越不同的线程,则需要使用合适的连接类型来确保线程安全性。通常情况下,当信号和槽跨越不同的线程时,应该使用Qt::QueueConnection连接类型。

2.11.未定义的行为

        在连接信号和槽时,确保在运行时信号和槽都是有效的。如果信号或槽未定义,连接操作可能会失败。

3.总结

        遇到问题,根据上面列举的原因一一排查,具体现象具体分析,通常都能解决信号槽响应不了的情况。