I’m making a GUI application in Python using Tkinter that reads text out loud from PDF, DOCX, TXT, and images using gTTS.
The program works, but sometimes Tkinter window becomes unresponsive and shows “Not Responding” while the text-to-speech is running.
Here is the minimal code that reproduces the issue:
from gtts import gTTS
import tkinter as tk
from tkinter import *
from tkinter import filedialog
from tkinter import PhotoImage
import pyaudio
import os
from playsound import playsound
parent = tk.Tk()
parent.title("Title Screen")
image = PhotoImage(file=r"C:\Users\aksha\Downloads\Techlogo.png")
label = Label(parent, image=image)
label.pack()
label.image = image
parent.update()
def speak(words):
tts = gTTS(text=words, lang="en")
tts.save("output.mp3")
playsound("output.mp3")
os.remove("output.mp3")
intro = (
"...Hi this is a software to help you read text out loud.. please select a file.."
)
speak(intro)
name = filedialog.askopenfilename(
initialdir=r"C:\\",
filetypes=(
("PDF files", "*.pdf"),
("Word files", "*.docx"),
("Text files", "*.txt"),
("Image files", "*.jpg *.jpeg *.png"),
),
)
if name.endswith(".txt"):
with open(name, "r") as file:
x = file.read()
speak(x)
else:
x = "please try again"
speak(x)
speak("Task complete. You may close the window.")
parent.mainloop()
DISCLAIMER: I did not test this code before running it, and I don't know how well tkinter plays with asynchronous functions. This answer also assumes that @TheLizzard is correct in thinking that playsound blocks the main thread
When I want to run something on a different thread, I typically use asyncio.to_thread(). For example, you could run playsound in a different thread, then that should fix the 'Not Responding' dialog. Here is what your code would look like:
# Source - https://stackoverflow.com/q/79839637
# Posted by Akshadha Awasthi, modified by community. See post 'Timeline' for change history
# Retrieved 2025-12-06, License - CC BY-SA 4.0
from gtts import gTTS
import tkinter as tk
from tkinter import *
from tkinter import filedialog
from tkinter import PhotoImage
import pyaudio
import os
from playsound import playsound
import asyncio
parent = tk.Tk()
parent.title("Title Screen")
image = PhotoImage(file=r"C:\Users\aksha\Downloads\Techlogo.png")
label = Label(parent, image=image)
label.pack()
label.image = image
parent.update()
async def speak(words):
tts = gTTS(text=words, lang="en")
tts.save("output.mp3")
await asyncio.to_thread(playsound, "output.mp3") # Use asyncio.th_thread to run playsound in a different thread, making it so playsound doesn't block the main thread anymore
os.remove("output.mp3")
intro = (
"...Hi this is a software to help you read text out loud.. please select a file.."
)
speak(intro)
name = filedialog.askopenfilename(
initialdir=r"C:\\",
filetypes=(
("PDF files", "*.pdf"),
("Word files", "*.docx"),
("Text files", "*.txt"),
("Image files", "*.jpg *.jpeg *.png"),
),
)
if name.endswith(".txt"):
with open(name, "r") as file:
x = file.read()
asyncio.run(speak(x)) # Use asyncio.run to run speak so you don't get warning about a co routine not being awaited
else:
x = "please try again"
asyncio.run(speak(x)) # Use asyncio.run to run speak so you don't get warning about a co routine not being awaited
asyncio.run(speak("Task complete. You may close the window.")) # Use asyncio.run to run speak so you don't get warning about a co routine not being awaited
parent.mainloop()
You would just have to run pip install asyncio before running this to use the asyncio library. Hope this fixes your issue!