1
from tkinter import *
import pyttsx3

root = Tk()
root.geometry("800x500")


def talk():
    engine = pyttsx3.init()
    engine.say(my_entry.get())

    my_entry.delete(0, END)
    engine.runAndWait()


my_entry = Entry(root, font=("Helvetica", 28))
my_entry.pack(pady=20)
my_button = Button(root, text="Speak", command=talk)
my_button.pack(pady=20)
root.mainloop()

I am trying to run this simple program but the window only runs once and closes automatically. The Tkinter window closes after only running one time. Any suggestions? Some people suggested threading but I don't know how to use it, if anyone of you knows where I can learn that, it will be helpful.

Muzammil-cyber
  • 141
  • 1
  • 7
  • I don't see any obvious problems with your code. I suspect that an exception occurs in `pyttsx3`. Try running your script from the command line. That would at least *show* any exceptions that occur. – Roland Smith Sep 05 '22 at 17:30

2 Answers2

1

If you want to try running the pyttsx3 calls in a separate thread, it should be fairly straightforward to implement

import pyttsx3
from threading import Thread
from tkinter import *


root = Tk()
root.geometry("800x500")


def _talk_target():  # renamed 'talk' function for clarity
    engine = pyttsx3.init()
    engine.say(my_entry.get())

    my_entry.delete(0, END)
    engine.runAndWait()


def talk():  # this is now the 'talk' function that's called by 'my_button'
    tts = Thread(target=_talk_target)  # init a new thread to call '_talk_target'
    tts.start()  # run '_talk_target' in a new thread
    tts.join()  # rejoin the main thread


my_entry = Entry(root, font=("Helvetica", 28))
my_entry.pack(pady=20)
my_button = Button(root, text="Speak", command=talk)
my_button.pack(pady=20)
root.mainloop()
JRiggles
  • 4,847
  • 1
  • 12
  • 27
0

Work around:

from subprocess import call
phrase = "Hi everyone"
call(["python3", "speak.py", phrase])

where speak.py is:

import sys
import pyttsx3

def init_engine():
    engine = pyttsx3.init()
    return engine

def say(s):
    engine.say(s)
    engine.runAndWait() #blocks

engine = init_engine()
say(str(sys.argv[1]))
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Blue Robin Mar 02 '23 at 15:03