我正在创建一个使用tkinter和pyttsx与用户交互的小程序。由于某些原因,脚本在说“button clicked”之后退出,而它应该留在主循环中。更奇怪的是,它甚至没有通过我在主循环下面添加的“检查点”。在
以下是生成错误的代码的简化版本:
import Tkinter as tk
import pyttsx
def button_click():
engine.say('button clicked')
engine.runAndWait()
engine = pyttsx.init()
root = tk.Tk()
gameframe = tk.Frame(root)
gameframe.pack()
readybutton = tk.Button(gameframe, text = 'click', command = button_click)
readybutton.pack()
root.mainloop()
print('checkpoint')
如何解决这个问题?在
更新: 通过Google我发现一些迹象表明,这个问题可能与tkinter和pyttsx使用事件循环有关,也与苹果的Foundation和/或ObjC模块处理事件的方式有关。因为我是Python的新手,我不太理解它,但是你们中的一些人可能会,看http://comments.gmane.org/gmane.comp.python.pyobjc.devel/5965。在
mac也发现了一个非常简单的解决方法:
^{pr2}$这很好,也与tkinter结合使用:-)
是什么让你认为它正在退出主循环?如果它没有到达最后的print语句,主循环不是“exiting”,则程序崩溃。根据您提供的证据,崩溃发生在
engine.runAndWait()
方法中。在如果你的程序没有崩溃,你真正的意思是程序不再响应事件,那么唯一的解释就是
engine.runAndWait()
是阻塞的。我不知道为什么会发生这种情况,因为我从来没有使用过pyttsx,尽管runAndWait
的文档说它会阻塞,直到所有排队的事件都得到处理,也许它认为队列中还有什么东西。在当您从不同的线程调用其引擎方法时,pyttsx会崩溃,即使它们在时间上从未重叠。(不仅仅是运行并等待,而且类似于的东西也会说)startuop和runAndWaitblock。在
我不得不为pyttsx编写一个线程安全包装器。pyttsx中的所有函数都需要放在同一个线程中。在
如果您使用的是starturoop,请注意不要在命令队列为空时让“finished outrance”回调返回,否则您将无法再次访问循环,但startroop也不会返回。我想我在跑步和等待方面有问题。在
另外,打电话给发动机.停止回调中的似乎会使事情停止正常工作。(但是你也不能从任何地方调用它。)永远不要输入空字符串或非ascii字符。(可能依赖于平台)。在
相关问题 更多 >
编程相关推荐