Skip to main content
 首页 » 编程设计

python之防止 pyttsx3 卡住 GUI

2024年09月03日33sharpest

我已经构建了我的 Kivy GUI,它与 pyttsx3 一起用于语音输出,但是当我运行 pyttsx3 时它会阻塞主线程,从而导致 GUI 卡住。

我如何在另一个线程上运行 pyttsx3 并从主线程听到输出,或者有没有办法在不阻塞主线程的情况下运行 pyttsx3 并防止它卡住我的 Kivy GUI?

这是我创建的示例代码,当您单击按钮时,它应该从文本框中打印文本,但它会导致 GUI 在 pyttsx3 运行时卡住:

import pyttsx3 
from kivy.uix.textinput import TextInput 
from kivy.uix.floatlayout import FloatLayout 
from kivy.uix.button import Button 
from kivy.app import App 
 
 
 
engine = pyttsx3.init() 
 
engine.setProperty('rate', 150) 
engine.setProperty('volume', 1) 
 
class example(App): 
 
    def build(self): 
 
        layout = FloatLayout() 
 
        self.textbox = TextInput(text="", multiline=False, font_size=12, size_hint_y=None, size_hint_x=None, width = 150, height = 30, pos_hint= {"x":0.4, "y":0.8}) 
 
 
 
        self.btnText = Button(text="Print text", font_size=12, size_hint_y=None, size_hint_x=None, width = 150, height = 30, pos_hint= {"x":0.4, "y":0.6}) 
        self.btnText.bind(on_press=self.print) 
 
 
        layout.add_widget(self.textbox) 
        layout.add_widget(self.btnText) 
 
        return layout 
 
    def print(self, instance): 
        engine.say("this is an example of kivy being blocked my pyttsx3") 
        engine.runAndWait() 
        print(self.textbox.text) 
 
 
 
if __name__ == '__main__': 
    example().run() 

我尝试在下面这样做:

thread2 = threading.Thread(target=engine.say, args = ("some text here",)) 
thread2 = threading.Thread(target=engine.runAndWait(),) 
thread2.start() 
thread2.join() 

但上面的代码仍然阻塞线程并导致 Kivy GUI 卡住。

请您参考如下方法:

正如他指出的那样,您必须在一个线程中运行它:

import threading 
 
# ... 
 
class example(App): 
    # ... 
 
    def print(self, instance): 
        threading.Thread( 
            target=self.run_pyttsx3, args=(self.textbox.text,), daemon=True 
        ).start() 
 
    def run_pyttsx3(self, text): 
        engine.say(text) 
        engine.runAndWait() 
 
# ...