2011-12-27 7 views
0

tkinterとpyttsxを使用してユーザーとやりとりする小さなプログラムを作成しています。なんらかの理由で、スクリプトは「ボタンをクリックした」と言った後に終了しますが、メインループに留まる必要があります。見知らぬ人でさえ、メインループの下に追加した「チェックポイント」を通過することさえありません。この問題を解決するための方法pyttsxでテキストを話した後、Tkinter mainloopが突然終了する

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') 

ここでエラーが発生したコードの簡易版ですか?

更新: via Googleこの問題は、イベントループを使用するtkinterとpyttsxの両方と、AppleのFoundationおよび/またはObjCモジュールがイベントをどのように処理するかと関係している可能性があります。私はPythonの初心者ですから、私はそれをうまく理解できませんが、あなたの中にはhttp://comments.gmane.org/gmane.comp.python.pyobjc.devel/5965があります。

また、私は完全にpyttsx使用して回避し、ほとんどがあまりに単純で、MAC-固有の回避策が見つかりました:これはあなたを作る何も

答えて

0

:-)のTkinterとの組み合わせで、うまく機能

import os 

phrase = 'button clicked' 
os.system("/usr/bin/say " + phrase) 

をメインループを終了していると思いますか?最終的なprintステートメントに到達していない場合、メインループは「終了」していないので、プログラムがクラッシュしています。あなたが与えている証拠に基づいて、方法はengine.runAndWait()で起きています。

プログラムがクラッシュしていない場合、プログラムがイベントに応答しなくなったということは、engine.runAndWait()がブロックされているということだけです。なぜそれが起こっているのですか?私は決してpyttsxを使ったことがないので、わからないのですが、runAndWaitのドキュメントでは、キューに入れられたすべてのイベントが処理されるまでブロックされると言われています。

+0

本当にメインループを終了するかどうかはわかりません。 runAndWait()メソッドでクラッシュする可能性があります。ここに私が見るものがあります:プログラムが「ボタンをクリック」した後、コードの最後に達したように終了します。作成されたTkinter GUI(ボタン)が消え、Terminal(mac)がコマンドライン入力モードに戻ります。また、エラーメッセージも表示されません。 –

0

pyttsxは、エンジンメソッドを別のスレッドから呼び出すと、たとえ重複していなくても分解されます。 (ちょうどrunAndWaitしかしのようなものは、あまりにも、を言うわけではありません。)startLooprunAndWaitブロック。

私はpyttsxの周りにスレッドセーフラッパーを書く必要がありました。 pyttsxのすべての関数は同じスレッドに入る必要があります。

あなたはstartLoopを使用している場合は、コマンドキューが空である、またはあなたが再びループにアクセスすることができますが、startLoopないとき「完成発言」コールバックのリターンをさせないように注意してくださいどちらも返されません。私はrunAndWaitで問題があったと思います。

また、コールバックからEngine.stopを呼び出すと、正常に動作しなくなる可能性があります。 (ただしどこからでも呼び出すことはできません)と言うと、と言う文字列は空文字列か非ASCII文字です。 (プラットフォームによって異なる可能性があります)。