You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Qt 6.3环境下QThread发射信号后槽函数无响应问题

问题根因

最直接导致信号无响应的原因是槽函数名拼写错误,信号槽根本没有连接成功:
你在dialog.cpp中写的连接代码用了旧版字符串宏语法:

connect(m_Thread1, SIGNAL(NumberChanged(int)), this, SLOT(Update_01(int)));

这里你写的槽名是Update_01,中间是数字0,但你在头文件声明、cpp中实际实现的槽函数是Update_O1,中间是大写字母O。旧版SIGNAL/SLOT宏是字符串匹配机制,不会在编译阶段检查函数是否存在、签名是否匹配,只会在运行时悄悄在应用输出面板打印连接失败的警告,不会中断程序运行,所以你没注意到连接从一开始就没建立,信号发射后自然没有槽函数响应。

除此之外你的代码还有几个会影响运行稳定性的隐患:

  • 互斥锁用法完全错误:你在while循环内部每次创建局部QMutex实例,不同迭代锁的根本不是同一个锁对象,完全起不到线程同步保护Stop标志的作用,存在多线程数据竞争风险。
  • 工作线程循环没有加任何延时,逻辑会占满1个CPU核心,信号发射频率过高,可能导致主线程事件循环阻塞,无法及时处理收到的信号。
  • 直接继承QThread重写run的方式虽然能实现需求,但很容易踩线程事件循环的坑,Qt官方更推荐将业务逻辑封装到独立的QObject子类中,通过moveToThread挂载到线程实例运行。
修复步骤
  1. 修正信号槽连接,优先换成Qt5之后支持的新式函数指针连接语法,这种语法会在编译阶段检查函数名、签名是否正确,写错了直接编译报错,不会把问题留到运行时:
    // 替换原来的旧语法connect语句
    connect(m_Thread1, &MyThread::NumberChanged, this, &Dialog::Update_O1);
    
    改完之后如果还有拼写错误,编译阶段就会直接报错,不用等到运行时排查。
  2. 修正互斥锁逻辑:把QMutex改成MyThread类的私有成员,不要在循环里局部创建,推荐用QMutexLocker自动管理锁的释放,避免漏写unlock导致死锁:
    首先在mythread.h的私有成员区加锁定义:
    private:
        QMutex m_mutex;
        int Snum = 10;
        // 其他原有成员不变
    
    然后修改run函数的逻辑,加上适当延时降低CPU占用:
    void MyThread::run()
    {
        while(true)
        {
            {
                QMutexLocker locker(&m_mutex);
                if (Stop || Snum == 1) break;
            }
    
            if(Snum % 2 == 0)
            {
                Snum /= 2;
            }else{
                Snum = Snum * 3 + 1;
            }
            emit NumberChanged(Snum);
            // 加100ms延时,避免占满CPU,也方便观察数值变化
            QThread::msleep(100);
        }
    }
    
  3. 后续实现停止线程逻辑时,不要调用terminate()暴力终止,只需要把Stop标志设为true,等线程自然退出循环后调用wait()回收线程资源即可。

排查信号槽不触发问题时,优先看Qt Creator底部的「应用程序输出」面板,旧语法连接失败时会打印明确的错误提示,比如QObject::connect: No such slot Dialog::Update_01(int),可以直接定位问题。

内容的提问来源于stack exchange,提问作者Martin Sieburg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 19:06:43