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

PyQt5语音识别GUI无响应求助:持续监听时界面卡顿

解决PyQt5 GUI因语音监听阻塞导致无响应的问题

问题原因

你的代码里Listen()函数的无限while循环直接在GUI主线程中执行,而Qt的GUI运行依赖主线程的事件循环(app.exec_())。由于Listen()一直占用主线程,app.exec_()根本没机会启动,导致GUI无法处理任何交互事件,表现为无响应。虽然语音识别功能能正常工作(控制台有输出),但界面彻底卡死。

解决方案:使用Qt多线程分离语音监听任务

把语音监听逻辑放到独立的子线程中,让主线程专注处理GUI事件循环。Qt提供了QThread类来实现多线程,下面是修改后的完整代码:

import sys
import speech_recognition as sr
from PyQt5.QtWidgets import QApplication, QWidget, QDesktopWidget
from PyQt5.QtCore import QThread, pyqtSignal

class ListenThread(QThread):
    # 可选信号:如需将识别结果传回GUI线程可使用
    recognized_signal = pyqtSignal(str)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.r = sr.Recognizer()
        self.is_running = True

    def run(self):
        while self.is_running:
            with sr.Microphone() as source:
                print("listen")
                self.r.adjust_for_ambient_noise(source)
                audio = self.r.listen(source)
            try:
                user = self.r.recognize_google(audio)
                print(user)
                # 发送识别结果信号(若需更新GUI可连接此信号)
                self.recognized_signal.emit(user)
                if "hey" in user.lower():  # 统一转小写,简化大小写判断
                    print("Hello")
            except Exception as e:
                print(f"识别出错: {e}")

    def stop(self):
        self.is_running = False
        self.quit()
        self.wait()

def window():
    app = QApplication(sys.argv)
    widget = QWidget()   
    widget.setWindowOpacity(0.10)
    screen = QDesktopWidget().screenGeometry()
    widget.setFixedSize(480, 960)
    w = widget.geometry()
    x = screen.width() - w.width()
    y = screen.height() - w.height()
    widget.move(x, y)
    widget.show()

    # 创建并启动监听线程
    listen_thread = ListenThread()
    listen_thread.start()

    # 应用退出时安全停止线程
    app.aboutToQuit.connect(listen_thread.stop)

    sys.exit(app.exec_())

window()

关键改动说明

  • 新建ListenThread类继承QThread,将语音监听逻辑放入run()方法,作为子线程的执行入口。
  • 用is_running标志控制循环,确保线程能安全停止。
  • 在GUI主线程中启动子线程后,正常启动Qt事件循环app.exec_(),主线程不再被阻塞,GUI可正常响应操作。
  • 绑定app.aboutToQuit信号与线程stop()方法,避免应用退出时线程残留导致资源泄漏。
  • 优化关键词判断:通过user.lower()统一转小写,无需分别判断大小写形式。

修改后,语音监听在后台子线程运行,GUI主线程能正常处理事件,界面不会再出现无响应的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 12:40:50