2016-07-19 8 views
1

私はTkinterを使ってユーザからの入力を受け取る他の人のためのいくつかのPythonプログラムを開発しました。シンプルでユーザーフレンドリーなものにするために、コマンドラインやPythonコンソールは決して立ち上がらない(つまり、.pywファイルが使われる)ので、私はロギングライブラリを使って、例外が発生します。しかし、私は実際に例外をキャッチするのが難しいです。たとえば:Pythonを使ってTkinterで例外を保存する

import logging 
logging.basicConfig(filename='errors.log', level=logging.ERROR) 

try: 
    cause_an_error() 
except: 
    logging.exception('simple-exception') 

予想したように、プログラムエラー、およびログへの書き込み:

def cause_an_error(): 
    a = 3/0 

は、今、私たちは通常、エラーを記録しよう:

私たちは、エラーが発生します関数を記述しますerrors.logへのエラー。コンソールに何も表示されません。 Tkinterをウィンドウ内のボタンを押すと、この場合

import logging 
import Tkinter 
logging.basicConfig(filename='errors.log', level=logging.ERROR) 

try: 
    root = Tkinter.Tk() 
    Tkinter.Button(root, text='Test', command=cause_an_error).pack() 
    root.mainloop() 
except: 
    logging.exception('simple-exception') 

エラーが発生します。私たちはそのようなTkinterのインターフェイスを実装する場合しかし、異なる結果があります。しかし、この時は、何もファイルに書き込まれていない、と次のエラーがコンソールに表示されます。

Exception in Tkinter callback 
Traceback (most recent call last): 
    File "C:\Python27\lib\lib-tk\Tkinter.py", line 1536, in __call__ 
    return self.func(*args) 
    File "C:/Users/samk/Documents/GitHub/sandbox/sandbox2.pyw", line 8, in cause_an_error 
    a = 3/0 
ZeroDivisionError: integer division or modulo by zero 

は、このエラーをキャッチし、ログに記録する別の方法はありますか?

+0

Tkinterのは、独自のスレッド上で動作し、root.mainloop' 'の後に来るすべてのものは、後にのみ実行されますあなたは窓を閉じる。 'cause_an_error'は、ボタンをクリックしたときにのみ実行されますが、最初に' root.mainloop'が実行されます。おそらく、例外が捕捉されていないということは、別の "環境"に投げ込まれているからです...もっと詳細で技術的な答えが出てくることを願っています。興味深いもの: – nbro

+0

今、あなたがそれに言及しても、 'raise'コマンドはエラーも取り出すことができないので、別の環境では間違いなくスローされているようです。インポート後にTkinterのエラー処理を変更してロギングを含める方法はありますか? –

+0

あなたは関数の例外を直接キャッチすることができます... – nbro

答えて

2

これはあまり詳しく書かれていませんが、tkinterはコールバックの結果として起こる例外のためのメソッドを呼び出します。ルートウィンドウに属性report_callback_exceptionを設定することで、独自の方法で任意の操作を行うことができます。例えば

:参考

import tkinter as tk 

def handle_exception(exception, value, traceback): 
    print("Caught exception:", exception) 

def raise_error(): 
    raise Exception("Sad trombone!") 

root = tk.Tk() 
# setup custom exception handling 
root.report_callback_exception=handle_exception 

# create button that causes exception 
b = tk.Button(root, text="Generate Exception", command=raise_error) 
b.pack(padx=20, pady=20) 

root.mainloop() 

+0

完璧、ありがとう! :)行番号または例外を生成した関数を取得する方法はありますか? –

+1

@SamKrygsheld: 'traceback'引数を見てください。 –

+0

ああ、ありがとう。将来これを見る人にとっては、渡されるトレースバックは文字列だと仮定していましたが、実際はトレースバックオブジェクトです。 traceback.tb_linenoを使用すると、行番号にアクセスできます。 –

関連する問題