QObject::connect报错无对应槽:Q_OBJECT宏及多实例化问题排查
解决QObject::connect: No such slot错误的问题
首先咱们直接戳中问题核心:你用的是Qt旧版的SIGNAL/SLOT宏语法,而QTimer::timeout()信号是没有参数的,但你试图在槽函数里传递_i参数,这就导致信号和槽的签名完全不匹配,Qt找不到对应的槽函数,所以抛出了这个错误。
至于为什么单个实例没引起注意?其实大概率也触发了错误,只是输出信息没那么显眼,当你实例化4个对象时,重复的错误信息才让你注意到问题。
接下来给你几个可行的解决方案,按推荐程度排序:
方案1:改用Qt5+的新信号槽语法(强烈推荐)
新语法支持lambda表达式,不仅能直接绑定参数,还能在编译时检查信号槽的匹配性,从根源避免这类运行时错误。修改你的qtCPUBar构造函数即可:
qtCPUBar::qtCPUBar(int i) { _i = i; auto *timer = new QTimer(this); // 用新语法+lambda绑定成员变量_i connect(timer, &QTimer::timeout, this, [this]() { showCPU(_i); }); timer->start(1000); showCPU(_i); resize(150, 60); }
这种方式不需要修改showCPU函数的签名,直接通过lambda把成员变量传递给槽函数,完美解决参数匹配问题。
方案2:利用类成员变量,修改槽函数为无参数
既然_i已经是qtCPUBar的私有成员,完全可以让showCPU直接使用这个变量,不需要额外传参:
第一步:修改HPP文件的槽函数声明
class qtCPUBar : public QProgressBar{ Q_OBJECT public: virtual ~qtCPUBar() = default; qtCPUBar(int i); private slots: // 去掉参数,直接用类成员_i void showCPU(); private: int _i = 0; };
第二步:修改CPP文件的槽函数实现
void qtCPUBar::showCPU() { CPUStats cpu; cpu.updateInfo(); auto tot = cpu._CPUInfo._Frequence; // 直接使用成员变量_i auto la = (cpu.getInfo(_i, CPUStats::CORE_USAGE)).back(); auto res = 100 * la / tot; this->setValue(static_cast<int>(res)); }
第三步:修改构造函数中的connect语句
connect(timer, SIGNAL(timeout()), this, SLOT(showCPU()));
现在信号(无参数)和槽(无参数)的签名完全匹配,Qt就能正常找到对应的槽函数了。
额外注意事项
- 务必重新运行
qmake:因为Q_OBJECT宏需要Qt的moc工具生成额外代码,如果修改了包含Q_OBJECT的头文件,一定要重新运行qmake或者clean后重新构建项目,否则可能依然会出现槽函数找不到的问题。 - 尽量弃用旧的
SIGNAL/SLOT宏:新语法不仅更安全(编译时检查错误),写法也更灵活,是Qt官方推荐的标准用法。
内容的提问来源于stack exchange,提问作者Benjamin Sx
相关产品推荐
相关产品推荐

