I am creating a voice assistant that can speak and hear (using Python). While I was adding the speaking feature I programmed it to greet while the programme starts. I was multithreading the programme because the speak functions take to much time, it hangs the programme and it looks like it has stopped. While I was multithreading the speak function using pyttsx3 library of python, this error comes: "Runtime Error: the run loop has already started". My code:
from threading import Thread
from tkinter import *
from ctypes import windll, byref, create_unicode_buffer, create_string_buffer
import pyttsx3
import datetime
FR_PRIVATE = 0x10
FR_NOT_ENUM = 0x20
def load_font(font_path, private=True, enumerable=True):
path_buf = None
add_font_resource_ex = None
if isinstance(font_path, bytes):
path_buf = create_string_buffer(font_path)
add_font_resource_ex = windll.gdi32.AddFontResourceExA
elif isinstance(font_path, str):
path_buf = create_unicode_buffer(font_path)
add_font_resource_ex = windll.gdi32.AddFontResourceExW
flags = (FR_PRIVATE if private else 0) | (FR_NOT_ENUM if not enumerable else 0)
num_fonts_added = add_font_resource_ex(byref(path_buf), flags, 0)
return bool(num_fonts_added)
class MainWindow(Tk):
def __init__(self):
super().__init__()
self.title("Voice Assistant")
self.geometry("550x505")
self.resizable(False, False)
self.engine = pyttsx3.init()
self.output_area = Text(self, bd=2, relief=SOLID, font=("Poppins", 16), width=40, height=12, state=DISABLED)
self.output_area.place(x=10, y=10)
self.command_en = Entry(self, font=("Poppins", 11), width=48)
self.command_en.place(x=10, y=465)
self.hear_btn = Button(self, text="Hear", font=("Arial", 10), width=9, height=1)
self.hear_btn.place(x=455, y=465)
self.wish_me()
self.mainloop()
def speak(self, audio):
self.engine.say(audio)
self.engine.runAndWait()
def say(self, audio):
speak_thread = Thread(target=self.speak, args=[audio])
speak_thread.start()
def wish_me(self):
hour = int(datetime.datetime.now().hour)
if 0 <= hour < 12:
self.say("Good morning")
elif 12 <= hour <= 18:
self.say("Good afternoon")
else:
self.say("Good evening")
self.say("I am Jarvis, How can I help you?")
if __name__ == "__main__":
loaded = load_font("Poppins-Regular.otf")
root = MainWindow()
Error:
Exception in thread Thread-2:
Traceback (most recent call last):
File "C:\Users\Manbir Singh Judge\Python 3.8.6\lib\threading.py", line 932, in _bootstrap_inner
self.run()
File "C:\Users\Manbir Singh Judge\Python 3.8.6\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "C:/Users/Manbir Singh Judge/PycharmProjects/Voice Assistant/main.py", line 56, in speak
self.engine.runAndWait()
File "C:\Users\Manbir Singh Judge\Python 3.8.6\lib\site-packages\pyttsx3\engine.py", line 177, in runAndWait
raise RuntimeError('run loop already started')
RuntimeError: run loop already started