pythontkinterplaysoundgtts

Timer stops updating when an audio is played


I have used after() method to update the time remaining for quiz and converted text of question to audio using gtts module and played that using playsound module. But when the audio is played timer stops updating. How can I fix it?

import playsound
import tkinter
import gtts
import os

def speak_que():
    global audio_no
    sound = gtts.gTTS(question_label["text"], lang = "en")
    file_name = "Audio_" + str(audio_no) + ".mp3"
    sound.save(file_name)
    playsound.playsound(file_name)
    os.remove(file_name)
    audio_no += 1

def change_time():
    pre_time = int(time_label["text"])
    if pre_time != 1:
        time_label.config(text = pre_time-1)
        time_label.after(1000, change_time)
    else:
        window.destroy()

window = tkinter.Tk()
audio_no = 0
time_label = tkinter.Label(window, text = "15")
time_label.after(1000, change_time)
question_label = tkinter.Label(window, text = "What is the sum of 4 and 2")
answer = tkinter.Entry(window)
speak = tkinter.Button(window, text = "Speak", command = speak_que)
time_label.pack()
question_label.pack()
answer.pack()
speak.pack()
window.mainloop()

Solution

  • First, make sure your speak_que() routine is completing, if not, you can install the older version of playsound 1.2.2 as the newest version tends to have issues.

    pip uninstall playsound
    
    pip install playsound==1.2.2
    

    Next, if you want the timer to continue during speak_que() (or any two operations in parallel); you'll have to use threading, see below.

    import playsound
    import tkinter
    import gtts
    import os
    from threading import *
    
    def speak_que():
        global audio_no
        sound = gtts.gTTS(question_label["text"], lang = "en")
        file_name = "Audio_" + str(audio_no) + ".mp3"
        sound.save(file_name)
        playsound.playsound(file_name)
        os.remove(file_name)
        audio_no += 1
    
    def threadedSound():
        t1=Thread(target=speak_que)
        t1.start()
    
    def change_time():
        pre_time = int(time_label["text"])
        if pre_time != 1:
            time_label.config(text = pre_time-1)
            time_label.after(1000, change_time)
        else:
            window.destroy()
    
    window = tkinter.Tk()
    audio_no = 0
    time_label = tkinter.Label(window, text = "15")
    time_label.after(1000, change_time)
    question_label = tkinter.Label(window, text = "What is the sum of 4 and 2")
    answer = tkinter.Entry(window)
    speak = tkinter.Button(window, text = "Speak", command = threadedSound)
    time_label.pack()
    question_label.pack()
    answer.pack()
    speak.pack()
    window.mainloop()