Программа перестает использовать tkinter с pyttsx3, почему?

#python-3.x #tkinter #pyttsx3

#python-3.x #tkinter #pyttsx3

Вопрос:

Я гуглю уже почти неделю, и я знаю, что есть похожие вопросы, но ни у одного из них нет ответа. Итак, вот еще один, который, надеюсь, приведет к ответу. Я написал небольшую программу для своего ребенка, в которой появляется слово, произносится, и после очистки слова ей нужно его воспроизвести. Я использовал pyttsx3 в качестве речевого модуля, потому что он доступен в автономном режиме. Программа работает нормально, но просто чтобы сделать ее более привлекательной для нее, я решил создать графический интерфейс с помощью tkinter. Теперь происходит то, что окно построено, слово shows up произносится, но после этого программа завершает работу без каких-либо ошибок. Чтобы проверить, как далеко выполняется программа, я использовал команду печати после каждой строки. Команды печати выполняются и отображаются в терминале. Все остальные промежуточные строки, связанные с tkinter, не выполняются. Я попытался создать другую функцию для механизма speak, происходит то же самое.

Итак, еще раз: pyttsx3 работает нормально, как и tkinter, но вместе в одной программе — нет. если вы удалите строку engine.runAndWait(), программа выполняется нормально, просто без речи.

Почему это происходит и как я могу это решить? Мне очень жаль, пожалуйста, объясните мне это, как будто я 40-летний домохозяин, который пытается освоить новый навык без какого-либо опыта программирования или CS, спасибо.

Вот мой код, извините, если он немного запутанный, только начал несколько недель назад 🙂

 import tkinter as tk
import sys, json, random, pyttsx3

#setup window
window = tk.Tk()
window.geometry("500x500")
window.title("Aliyah's dictee spel")
window.configure(background = "black")

#my photo
photo1 = tk.PhotoImage(file="dictee.gif")
tk.Label (window, image=photo1, bg="black") .grid(row=0, column=0)

def main():
    """Setting up the game"""
    global WORDS_CORRECT, WORDS_WRONG, WORDS
    WORDS_CORRECT = 0
    WORDS_WRONG = 0
    with open('vocabulary.json') as json_file:
        data = json.load(json_file)
        WORDS = data["words"]
    for widget in window.winfo_children():
        widget.destroy()
    tk.Label (window, image=photo1, bg="black") .grid(row=0, column=0)
    tk.Label (window, text = "Dit is het dictee spel voor Aliyah. Wil je beginnen?", bg="black", fg="white", font="none 12 bold") .grid(row=1)
    tk.Button(window, text="Ja", width=6, command=lambda: dictee(WORDS)) .grid(row=2, column=0)
    tk.Button(window, text="Nee", width=6, command=sys.exit) .grid(row=2, column=1)
    tk.Button(window, text="Bewerk lijst", width=10, command=manage_list) .grid(row=3, column=1)

#def speak(WORD): this did not work, even the last print command in dictee() is executed in terminal
    #engine = pyttsx3.init()
    #nl_voice_id = "com.apple.speech.synthesis.voice.ellen"
    #engine.setProperty('rate', 100)
    #engine.setProperty('voice', nl_voice_id)
    #engine.say(WORD)
    #engine.runAndWait()


def dictee(WORDS):
    """Show random words and ask for input."""
    if WORDS == []:
        for widget in window.winfo_children():
            widget.destroy()
        tk.Label (window, image=photo1, bg="black") .grid(row=0, column=0)
        tk.Label (window, text = "Dat waren alle woordjes.", bg="black", fg="white", font="none 12 bold") .grid(row=1, column=0)
        tk.Label (window, text = "Woordjes goed: %d" % WORDS_CORRECT, bg="black", fg="white", font="none 12 bold") .grid(row=2, column=0)
        tk.Label (window, text = "Woordjes fout: %d" % WORDS_WRONG, bg="black", fg="white", font="none 12 bold") .grid(row=3, column=0)
        tk.Label (window, text = "Wil je het nog een keer proberen?", bg="black", fg="white", font="none 12 bold") .grid(row=4, column=0)
        tk.Button(window, text="Ja", width=6, command=main) .grid(row=5, column=0)
        tk.Button(window, text="Nee", width=6, command=exit_game) .grid(row=5, column=1)
        window.update()
    else:
        random.shuffle(WORDS)
        for widget in window.winfo_children():
            widget.destroy()
        WORD = WORDS[0]
        tk.Label (window, image=photo1, bg="black") .grid(row=0, column=0)
        word = tk.Label (window, text = WORD, bg="black", fg="white", font="none 20 bold")
        word.grid(row=1, column=0)
        window.update()
        #speak(WORD)this is related to speak()
        engine = pyttsx3.init()
        nl_voice_id = "com.apple.speech.synthesis.voice.ellen"
        engine.setProperty('rate', 100)
        engine.setProperty('voice', nl_voice_id)
        engine.say(WORD) #WORD is being said!
        engine.runAndWait()#<< if you remove this line, the program is executed fine, but without speech
        #engine.stop() this did not work
        window.after(3000)
        print('after after')#all print commands after this are executed in terminal, all other lines are not executed
        word['text'] = ''
        print('after clear text')
        window.update()
        print('after update')
        ANSWER = tk.Entry(window, width=20, bg="white")
        print('after creating entry box')
        ANSWER.grid(row=2, column=0)
        print('after positioning entry window')
        tk.Button(window, text="Check", width=6, command=lambda: check(ANSWER,WORD)) .grid(row=3, column=0)
        print('after creating button')
        WORDS.remove(WORD)
        print('after words.remove')

def check(ANSWER, WORD):
    '''Cross check word shown with answer given'''
    global WORDS_CORRECT, WORDS_WRONG
    if ANSWER.get() == WORD:
        tk.Label (window, text = "Wat goed!", bg="black", fg="white", font="none 12 bold") .grid(row=4, column=0)
        WORDS_CORRECT  = 1
    else:
        tk.Label (window, text = "Jammer!", bg="black", fg="white", font="none 12 bold") .grid(row=4, column=0)
        WORDS_WRONG  = 1

    tk.Label (window, text = "Wil je het nog een keer proberen?", bg="black", fg="white", font="none 12 bold") .grid(row=5, column=0)
    tk.Button(window, text="Ja", width=6, command=lambda: dictee(WORDS)) .grid(row=6, column=0)
    tk.Button(window, text="Nee", width=6, command=exit_game) .grid(row=6, column=1)


def manage_list():
    '''manage the list of words by user'''
    with open('vocabulary.json', "r") as f:
        data = json.load(f)
        WORDS = data["words"]
    for widget in window.winfo_children():
        widget.destroy()
    window.update()
    tk.Label (window, text = "Dit zijn alle woorden in de vocabulaire", bg="black", fg="white", font="none 12 bold") .grid(row=0, column=0)
    tk.Label (window, text = WORDS, bg="black", fg="white", font="none 12 bold") .grid(row=1, column=0)
    tk.Label (window, text = "Wil je woorden toevoegen of verwijderen?", bg="black", fg="white", font="none 12 bold") .grid(row=2, column=0)
    tk.Button(window, text="alles verwijderen", command=lambda: clear_words('vocabulary.json')) .grid(row=5, column=0)
    words_to_add = tk.Entry(window, width=40, bg="white")
    words_to_add.grid(row=3, column=0)
    tk.Button(window, text="toevoegen", width=6, command=lambda: add_words('vocabulary.json', words_to_add.get())) .grid(row=8, column=2)
    tk.Button(window, text="hoofdmenu", width=6, command=main) .grid(row=10, column=0)

def add_words(filename, wordt_text):
    with open(filename, "r ") as f:
        data = json.load(f)
        data["words"].extend(wordt_text.split())
        f.seek(0)
        json.dump(data, f, indent=4)
    manage_list()

def clear_words(filename):
    with open('vocabulary.json', "w ") as f:
        data = {"words":[]}
        json.dump(data, f, indent=4)
    manage_list()

def exit_game():
    '''summarize results and exit after pushing enter'''
    for widget in window.winfo_children():
        widget.destroy()
    tk.Label (window, image=photo1, bg="black") .grid(row=0, column=0)
    tk.Label (window, text = "Tot de volgende keer.", bg="black", fg="white", font="none 12 bold") .grid(row=1, column=0)
    tk.Label (window, text = "Woordjes goed: %d" % WORDS_CORRECT, bg="black", fg="white", font="none 12 bold") .grid(row=2, column=0)
    tk.Label (window, text = "Woordjes fout: %d" % WORDS_WRONG, bg="black", fg="white", font="none 12 bold") .grid(row=3, column=0)
    tk.Label (window, text = "Klik op OK om af te sluiten", bg="black", fg="white", font="none 12 bold") .grid(row=4, column=0)
    tk.Button(window, text="OK", width=6, command=sys.exit) .grid(row=5, column=0)


if __name__ == "__main__":
    main()

window.mainloop()
  

Вот файл vocabulary.json:

 {
    "words": [
        "huis",
        "muis",
        "bal",
        "vuur",
        "muur",
        "ik",
        "zon",
        "hok",
        "poep",
        "aap",
        "noot",
        "hij",
        "zij",
        "test",
        "woord"
    ]
}
  

вот ссылка на изображение, которое я использовал: https://www.obsbeekbergen.nl/wp-content/uploads/sites/34/2016/04/dictee.gif

Вывод в терминале при завершении работы программы (опять же, ошибок нет):

 after clear text
after update
after creating entry box
after positioning entry window
after creating button
after words.remove 
  

Я использую python 3.8.5 с macOS Mojave 10.14.6.

Комментарии:

1. Ваш код отлично работает в моей Windows 7 под управлением Python 3.8.6. Таким образом, проблема может быть связана с вашей установкой Python или связанных модулей для macOS.

2. @acw1668 Спасибо.. черт.. Я не знаю, хорошая это новость или плохая, хахаха, я установил все совсем недавно, ну, по крайней мере, теперь я знаю, что проблема не в коде. Спасибо за усилия и указание мне правильного направления.