QT Creator中信号发射后槽函数未调用的问题排查
问题:ClassA中的sl_classASaveDataFromClassB槽函数未被调用的原因及解决办法
问题描述
在ClassB中向ClassA的槽函数发射信号,期望ClassB::closeEvent被调用时触发该槽,但断点调试显示closeEvent已执行且信号已发射,槽函数却始终未执行。
事件流程:
- 程序启动时,ClassA构造函数尝试建立信号槽连接:
connect(ClassB::getInstance(), SIGNAL(&ClassB::sig_ClassBData(float,float)), this, SLOT(&sl_classASaveDataFromClassB(float,float))); - 用户进入通用配置界面,输入两个浮点值
blahA和blahB; - 用户点击“保存”按钮,触发
ClassB::on_btnDataSave_clicked(); - 该函数调用
this->close(),进而触发ClassB::closeEvent(QCloseEvent *event)并发射信号。
问题分析及解决办法
1. 信号槽连接语法错误(核心问题)
你混用了Qt旧版SIGNAL()/SLOT()宏和函数指针,这是错误用法:旧宏要求传入函数签名字符串,而Qt5及以后推荐使用基于函数指针的直接连接方式(无需宏)。
错误写法:
connect(ClassB::getInstance(), SIGNAL(&ClassB::sig_ClassBData(float,float)), this, SLOT(&sl_classASaveDataFromClassB(float,float)));
修正为Qt5+的正确连接方式:
connect(ClassB::getInstance(), &ClassB::sig_classBData, this, &ClassA_UI::sl_classASaveDataFromClassB);
2. 信号名称大小写不匹配
连接时写的是sig_ClassBData,但ClassB中实际定义并发射的信号是sig_classBData(class首字母为小写),名称不匹配导致连接无效。
3. 槽函数声明与定义的语法错误
- ClassA.h中,槽函数
sl_classASaveDataFromClassB缺少返回类型(必须为void); - ClassA.c中,槽函数定义缺少
::域解析符,正确写法应为void ClassA_UI::sl_classASaveDataFromClassB(...)。
修正后的ClassA.h槽声明:
public slots: void sl_classASaveDataFromClassB(float blahA, float blahB);
修正后的ClassA.c槽定义:
void ClassA_UI::sl_classASaveDataFromClassB(float latitude, float longitude) { qDebug() << "test"; }
4. ClassB中结构体指针变量名错误
ClassB的closeEvent中使用data->blahA,但实际定义的结构体指针是location,需改为location->blahA和location->blahB。
修正后的ClassB::closeEvent:
void ClassB::closeEvent(QCloseEvent *event) { qDebug() << "closeEvent" ; emit sig_classBData(location->blahA, location->blahB); event->accept(); }
5. 其他潜在问题
- ClassB构造函数中,
data = new data;需改为location = new data;(结构体指针变量名为location); - 确保ClassA_UI对象在信号发射时未被销毁,否则槽函数无法执行。
修正后的关键代码片段
ClassA_UI构造函数
ClassA_UI::ClassA_UI(QWidget *parent, c_Instrument *Instrument) : QFrame(parent), ui(new Ui::ClassA_UI) { connect(ClassB::getInstance(), &ClassB::sig_classBData, this, &ClassA_UI::sl_classASaveDataFromClassB); }
ClassB构造函数
ClassB::ClassB(QWidget *parent) : QWidget(parent), ui(new Ui::ClassB) { ui->setupUi(this); location = new data; // 修正指针赋值 connect(this, &ClassB::sig_ClassBUpdateBox, this, &ClassB::sl_GeoLocationUpdateBox, Qt::QueuedConnection); }
内容的提问来源于stack exchange,提问作者jabroni
相关产品推荐
相关产品推荐

