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

基于Python Tkinter开发语音助手遇两类技术问题求助

Fixing Two Critical Issues in Your Tkinter Voice Assistant

Let's break down your two issues and fix them step by step:


Issue 1: Infinite Loop Repeating the Same Reply

Your assistant keeps spamming "I am doing jolly good, sir." because of two key problems in the reply() function:

  1. Broken condition logic: The line elif 'how are you' or 'what\'s up' in query: is always True (since non-empty strings evaluate to True in Python). This means no matter what your query actually says, this branch will trigger if none of the earlier conditions match.
  2. Unbounded while True loop: There's no mechanism to fetch a new query or exit the loop, so once this broken condition triggers, it runs forever.

Fix for Issue 1:

def reply():
    global query
    while True:
        # Exit condition to break the loop (add your own trigger phrase)
        if 'exit' in query or 'quit' in query:
            speak("Goodbye sir!")
            break
        
        # Logic for executing tasks based on query
        if 'wikipedia' in query:
            speak('Searching Wikipedia...')
            query = query.replace("wikipedia", "").replace("search", "").replace("for", "")
            results = wikipedia.summary(query.strip(), sentences=1)
            speak(f'According to Wikipedia, {results}')
        elif 'open youtube' in query:
            speak('Opening Youtube')
            webbrowser.open("https://youtube.com")
        elif 'open stack overflow' in query:
            speak('Opening StackOverflow')
            webbrowser.open("https://stackoverflow.com")
        elif 'what' in query and 'time' in query:
            strTime = datetime.datetime.now().strftime("%H:%M:%S")
            speak(f"Sir, The time is {strTime}")
        # Fixed condition check: both phrases need to be checked against query
        elif 'how are you' in query or 'what\'s up' in query:
            speak('I am doing jolly good, sir.')
        else:
            speak("Sorry, I didn't understand that.")
        
        # Fetch a new query after processing the current one
        query = listen_to_me()

Key changes made:

  • Fixed the broken elif condition to properly check if either phrase exists in query
  • Added an exit condition to break the loop when you say "exit" or "quit"
  • Added an else branch for unrecognized commands
  • Added query = listen_to_me() at the end of the loop to fetch a new voice input after each response

Issue 2: AttributeError When Converting Query to Lowercase

The error AttributeError: 'list' object has no attribute 'lower' happens because you're using show_all=True in r.recognize_google(). This parameter makes the function return a list of dictionaries (all possible recognition results) instead of a single string. When you try to call .lower() on a list, Python throws an error.

Fix for Issue 2:

Option 1 (Recommended: Use only the top recognition result):
Remove show_all=True to get a single string result, then you can safely convert it to lowercase:

def listen_to_me():
    msg2 = Message(root, text="Listening...", bg='yellow', font=('times', 14, 'italic'))
    msg2.place(x=200, y=220)  # Removed unused msg2.pack (it's redundant with place)
    with sr.Microphone() as source:
        audio = r.listen(source)
    global query
    try:
        # Removed show_all=True to get a single string result
        query = r.recognize_google(audio, language='en-IN')
        query = query.lower()  # Now this works!
        print(f"[Me]: {query}")
    except sr.UnknownValueError:
        engine.say("Sorry didn't quite catch that. Please repeat.")
        query = ""
    except sr.RequestError:
        engine.say("Sorry, I can't connect to the speech recognition service right now.")
        query = ""
    return query

Option 2 (If you need all recognition results):
If you must keep show_all=True, extract the transcript from the first result before calling .lower():

def listen_to_me():
    msg2 = Message(root, text="Listening...", bg='yellow', font=('times', 14, 'italic'))
    msg2.place(x=200, y=220)
    with sr.Microphone() as source:
        audio = r.listen(source)
    global query
    try:
        # Get all results as a list of dicts
        all_results = r.recognize_google(audio, language='en-IN', show_all=True)
        if all_results:
            # Extract the top result's transcript
            query = all_results['alternative'][0]['transcript'].lower()
            print(f"[Me]: {query}")
        else:
            engine.say("Sorry didn't quite catch that. Please repeat.")
            query = ""
    except sr.UnknownValueError:
        engine.say("Sorry didn't quite catch that. Please repeat.")
        query = ""
    except sr.RequestError:
        engine.say("Sorry, I can't connect to the speech recognition service right now.")
        query = ""
    return query

Key changes made:

  • Fixed the show_all=True issue by either removing it (for a single string) or extracting the transcript from the result list
  • Added proper error handling for speech recognition errors (UnknownValueError and RequestError)
  • Fixed the unused msg2.pack call (it's redundant with place())

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 07:52:37