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

如何让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()

关键改动说明:

  1. 导入线程模块:新增import threading,用来创建子线程运行语音监听逻辑。
  2. 启动监听线程:在每个训练窗口的mainloop()之前,用threading.Thread(target=SpeechRecognitionX, daemon=True).start()启动监听线程。daemon=True表示这个线程会随主线程退出而结束,避免程序退出后还有残留线程。
  3. 修改监听逻辑为循环:把原来的单次监听改成while True循环,这样可以持续监听用户指令,直到触发切换后退出线程。
  4. 异常处理:添加了语音识别常见的异常捕获,避免程序因为没听清或者网络问题崩溃。
  5. 指令转小写:把识别结果转成小写,避免用户说"Next"或者"NEXT"时无法匹配。

这样修改后,你打开Workout1窗口的同时,后台就会自动开始监听"next"指令,窗口也不会卡顿,完全符合你的需求~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:48:08