Qt信号槽连接失败或槽函数不响应的问题总结

一、Qt信号槽 连接失败或槽函数不响应的问题总结
使用Qt信号槽机制时,往往会出现信号与信号槽连接失败或信号槽不响应的情况,原因可能是以下几种情况:
1、检查拥有信号槽的类,是否继承了QObject,类没有声明Q_OBJECT。
2、信号槽没有定义为pubic slots或 private slots或 /protected slots
3、事件被子控件过滤掉了。比如QListWidget,当QListWidgetItem已经处理keypress事件后,QListWidget就不能响应itemDoubleClicked事件了。
4、 注意 connect的位置, 信号在创建信号槽连接前使用,则无法触发槽函数。
5. 信号函数未声明为 signals。
6. 某事件循环被阻塞导致信号未能发出。
7. 信号发出者和接收者的作用域,是否在信号发送前释放了接收者。
8. 信号和槽之间存在参数传递,但是二者的参数数量或者类型不一致(信号里的参数数量可以多于槽函数里的参数数量,但是二者都有的参数,类型必须对应)。
9. 信号槽的参数是自定义的,这时需要用qRegisterMetaType注册一下这种类型。具体操作可搜索qRegisterMetaType的使用。
示例:
// 注册这种自定义类型,首先添加头文件引用
#include
// 在connect之前注册参数类型
qRegisterMetaType > ("QList");
出现问题后,可按照上诉情况逐一排查。
二、connect函数调用几个限制
1、信号的发送者必须是QObject的派生类对象。不然会出现error: invalid conversion from ‘XXX*’ to ‘const QObject*’ [-fpermissive]…的错误。
2、回调槽函数的对象必须是QObject的派生类对象。不然会出现error: no matching function for call to ‘QObject::connect(XXX*,的错误。这里要注意一点,信号函数无论存在与否,都不会报错的。但是如果信号的发送者是NULL,那么会在运行的时候提示QObject::connect: Cannot connect (null)::信号函数() to 接收者::槽函数()的问题。
对于1,2两点,在connect函数调用的时候强转类型也可以通过编译,但是运行的时候会提示No such slot QObject::的问题。
3、槽函数所在的类的定义中必须添加宏Q_OBJECT,不然会出现QObject::connect: No such slot …的错误。
这里必须和第2点联系起来,如果添加了Q_OBJECT宏的类不是从QObject派生的,moc生成中间文件的时候会报错Error: Class contains Q_OBJECT macro but does not inherit from QObject。
如果添加了Q_OBJECT宏之后编译出现了undefined reference to ‘vtable for…的错误,请删除build目录下的Makefile文件,再重新生成。
4、信号函数的signals修饰和槽函数的slots修饰其实是必须的。虽然生成的中间代码中会去除掉。
5、如果槽函数是on_控件名_信号名那么不需要主动调用connnect进行连接。
三、当信号函数和槽函数带参数时,建议使用旧语法写信号槽连接。
当信号函数和槽函数有参数时,使用旧语法写信号/槽连接比新语法更容易发现错误。
QT5新语法写信号/槽连接,比如:
connect(Device::getInstance(), &Device::sig_sendData, this, &Tool::slot_receiveData);
旧语法写信号/槽连接,比如:
connect(Device::getInstance(), SIGNAL(sig_sendData(QString,int)), this, SLOT(slot_receiveData(QString, int));
 当修改了信号/槽函数其中一个函数的参数类型,而未修改另一个函数的参数类型时,例如:
信号函数sig_sendData(QString, int)变成了sig_sendData(QString, QByteArray),槽函数的参数类型未做相应的修改
新语法编译时会报错“Signal and slot arguments are not compatible.”,但是不会定位到错误发生的具体的信号/槽连接处,给调试和寻找错误带来了很大的不方便。
旧语法则会直接在信号/槽连接那里就报错,便于发现问题

你可能感兴趣的:(Qt,qt,开发语言)