如何让Tkinter窗口打开时后台运行SpeechRecognition1命令?
解决Tkinter窗口打开时立即启动语音监听的问题
嘿,我懂你的需求啦——你希望Workout1窗口一弹出来,后台就自动开始监听用户说"next",用来切换到下一个训练窗口对吧?
问题的核心在于Tkinter的mainloop()是阻塞主线程的,如果你直接在Workout1里调用SpeechRecognition1(),窗口会直接卡住,直到语音识别完成才会显示,这肯定不是你想要的效果。咱们用多线程就能解决这个问题,把语音监听的逻辑放到子线程里跑,这样主线程可以正常处理UI,后台监听也能持续运行。
下面是修改后的完整代码,我只改动了实现需求的关键部分,其他代码都保留了你原来的写法:
from tkinter import * import sys import speech_recognition as sr import threading # 新增:导入线程模块 def NextWorkout1(): workout1.destroy() Workout2() def Workout1(): global workout1 workout1 = Tk() workout1.geometry("300x44") workout1.configure(background="lightblue") workout1.resizable(0,0) workout1.title("Pressups") insLabel = Label(workout1, text="5 pressups", fg="red", bg="lightblue", font="Arial 25 bold") insLabel.pack() # 新增:启动语音监听的子线程,不阻塞UI主线程 threading.Thread(target=SpeechRecognition1, daemon=True).start() workout1.mainloop() def Workout2(): global workout2 workout2 = Tk() workout2.geometry("300x50") workout2.configure(background="lightblue") workout2.resizable(0,0) workout2.title("Starjumps") insLabel = Label(workout2, text="15 starjumps", fg="red", bg="lightblue", font="Arial 25 bold") insLabel.pack() # 同样,Workout2也可以启动对应的监听线程 threading.Thread(target=SpeechRecognition2, daemon=True).start() workout2.mainloop() def SpeechRecognition1(): r = sr.Recognizer() with sr.Microphone() as source: # 调整麦克风的噪音阈值,避免误识别 r.adjust_for_ambient_noise(source, duration=0.5) print("正在监听'next'指令...") while True: # 改成循环,持续监听 try: audio = r.listen(source, timeout=None) command = r.recognize_google(audio).lower() # 转小写,避免大小写问题 if command == "next": NextWorkout1() break # 切换后退出当前监听线程 else: print(f"识别到:{command},请说'next'切换训练") except sr.UnknownValueError: print("没听清,请再说一遍?") except sr.RequestError: print("网络问题,无法连接谷歌语音服务") def SpeechRecognition2(): global WorkoutNumber WorkoutNumber = 0 r = sr.Recognizer() with sr.Microphone() as source: r.adjust_for_ambient_noise(source, duration=0.5) print("正在监听'next'指令...") while True: try: audio = r.listen(source, timeout=None) command = r.recognize_google(audio).lower() if command == "next": # 这里你需要补充NextWorkout2的实现,我暂时留空 # NextWorkout2() print("准备切换到下一个训练") break else: print(f"识别到:{command},请说'next'切换训练") except sr.UnknownValueError: print("没听清,请再说一遍?") except sr.RequestError: print("网络问题,无法连接谷歌语音服务") Workout1()
关键改动说明:
- 导入线程模块:新增
import threading,用来创建子线程运行语音监听逻辑。 - 启动监听线程:在每个训练窗口的
mainloop()之前,用threading.Thread(target=SpeechRecognitionX, daemon=True).start()启动监听线程。daemon=True表示这个线程会随主线程退出而结束,避免程序退出后还有残留线程。 - 修改监听逻辑为循环:把原来的单次监听改成
while True循环,这样可以持续监听用户指令,直到触发切换后退出线程。 - 异常处理:添加了语音识别常见的异常捕获,避免程序因为没听清或者网络问题崩溃。
- 指令转小写:把识别结果转成小写,避免用户说"Next"或者"NEXT"时无法匹配。
这样修改后,你打开Workout1窗口的同时,后台就会自动开始监听"next"指令,窗口也不会卡顿,完全符合你的需求~
内容的提问来源于stack exchange,提问作者T Burnard
相关产品推荐
相关产品推荐

