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
相关产品推荐
相关产品推荐

