Qt多线程Signal&Slot未定义引用报错求助(切换基类无效)
问题解决:Qt线程间通信编译错误及逻辑修正
编译错误原因及解决步骤
1. 残留旧代码导致的未定义引用
错误信息中出现mclass相关未定义,但你提供的代码均为tthread类,说明项目可能残留旧的mclass文件或构建缓存:
- 删除项目的
debug/release构建目录 - 在Qt Creator中右键项目选择「运行qmake」
- 重新编译项目
2. Qt元对象工具(MOC)未正确生成代码
继承QObject并使用Q_OBJECT宏的类,必须通过MOC生成元对象代码:
- 确保
.pro文件中包含所有源文件:SOURCES += main.cpp tthread.cpp HEADERS += tthread.h - 修改头文件后需重新运行qmake,触发MOC更新
线程逻辑修正
你的代码存在线程启动逻辑错误,且无限循环会导致线程卡死,以下是修正后的完整代码:
tthread.h
#ifndef TTHREAD_H #define TTHREAD_H #include <QThread> #include <QObject> #include <QDebug> class tthread : public QObject { Q_OBJECT public: explicit tthread(QObject *parent = nullptr); void startWork(); // 重命名避免和QThread的start方法冲突 signals: void sec(int value); void minu(int value); public slots: void minutee(int value); void hourr(int value); private: void secondd(); // 改为私有方法,通过startWork触发执行 }; #endif // TTHREAD_H
tthread.cpp
#include "tthread.h" #include <QThread> tthread::tthread(QObject *parent) : QObject(parent) { } void tthread::startWork() { qDebug() << "线程启动" << QThread::currentThread(); secondd(); } void tthread::secondd() { int counter = 0; int sign = 1; while(true) { counter++; qDebug() << "秒计数器: " << counter << QThread::currentThread(); if(counter == 5) { emit sec(sign); counter = 0; qDebug() << "发送秒信号到分线程" << QThread::currentThread(); } QThread::msleep(100); // 添加休眠,避免线程占用100%CPU } } void tthread::minutee(int value) { int counter2 = 0; int sign2 = 1; while(true) { qDebug() << "收到秒信号值: " << value ; counter2++; qDebug() << "分计数器: " << counter2 ; if(counter2 == 5) { emit minu(sign2); counter2 = 0; qDebug() << "发送分信号到小时线程"; } QThread::msleep(100); } } void tthread::hourr(int value) { int counter3 = 0; while(true) { qDebug() << "收到分信号值: " << value ; counter3++; qDebug() << "小时计数器: " << counter3 ; if(counter3 == 5) { counter3 = 0; qDebug() << "小时计数器重置"; } QThread::msleep(100); } }
main.cpp
#include <QCoreApplication> #include <QThread> #include <QDebug> #include <QObject> #include "tthread.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QThread t1; QThread t2; QThread t3; tthread thread1; tthread thread2; tthread thread3; thread1.moveToThread(&t1); thread2.moveToThread(&t2); thread3.moveToThread(&t3); // 绑定线程启动信号到工作函数 QObject::connect(&t1, &QThread::started, &thread1, &tthread::startWork); // 线程间信号槽连接 QObject::connect(&thread1, &tthread::sec, &thread2, &tthread::minutee); QObject::connect(&thread2, &tthread::minu, &thread3, &tthread::hourr); // 启动QThread实例,而非自定义方法 t1.start(); t2.start(); t3.start(); return a.exec(); }
.pro文件(确保配置正确)
QT += core QT -= gui TARGET = triple CONFIG += c++17 SOURCES += main.cpp \ tthread.cpp HEADERS += tthread.h
关键修正说明
- 遵循Qt线程规范:调用
QThread::start()启动线程,通过QThread::started信号触发工作逻辑 - 在无限循环中添加休眠,避免线程占用全部CPU资源并阻塞事件循环
- 重命名自定义启动方法,避免与
QThread的start方法冲突 - 确保所有源文件被正确添加到项目配置中,保证MOC工具正常生成元对象代码
内容的提问来源于stack exchange,提问作者if4k
相关产品推荐
相关产品推荐

