2

関数呼び出しを行うプログラムを実行するとき

self.getFileButton = Button(self,
                            text = "...",
                            command =
                            tkFileDialog.askopenfilename(mode="r+b", **self.file_opt))

エラーが発生します

File "C:/Documents and Settings/l/My Documents/Python/csv_GUI.py", line 33, in create_widgets
tkFileDialog.askopenfilename(mode="r+b", **self.file_opt))

AttributeError: selectFile インスタンスに属性 'file_opt' がありません

4

3 に答える 3

7

おそらく次のようなものが必要です。

self.getFileButton = Button(self,
                            text = "...",
                            command = lambda: tkFileDialog.askopenfilename(mode="r+b", **self.file_opt))

問題は、あなたが書いたようaskopenfilenameに、ボタンが作成されたときに(クリックされたときではなく)関数が実行されることです。AttributeError に基づいて、file_optマッピングを作成する前にボタンを作成しますが、ボタンをクリックしたときに属性が存在すると仮定するfile_optと、適切な時期までルックアップ (および関数呼び出し) を延期する必要があります。

基本的にlambda、新しい関数を作成するだけです:

foo = lambda x : x*x

同等*:

 def foo(x):
     return x*x

このように書くとaskopenfilename、ボタンが実際にクリックされるまで関数の呼び出しを遅らせる理由が簡単にわかります。

*ラムダ関数が通常の関数とは異なる動作をする場合がいくつかありますが、この記事の目的上、それらについて心配する必要はありません。

于 2012-12-13T19:19:04.203 に答える
2

file_optたとえば、__init__メソッドや他の場所で実際にメンバーが定義されていますか?

問題が 1 つを定義していることであるが、 を実行した後であることが問題である場合はgetFileButton、順序を並べ替えることはできますか? そうでない場合は、mgilson のソリューションが適切です。しかし、それ以外の場合は、はるかに簡単です。

また、メンバーがどこにもない場合は、file_optさらに簡単です。存在しないものを渡そうとしないでください。

于 2012-12-13T19:45:25.640 に答える
1

一般的に言えば、ボタン関数自体で(ラムダを使用して)コールバック関数に引数を渡すことは避けるべきだと思います。それは醜く、pythonicではありません。

代わりに次のようにします。

def __init__(self, ...):
    ...
    Tkinter.Button(self, text='...', command=self.openfile).pack(...)
    ...

def openfile(self):
    return tkFileDialog.askopenfile(mode='r+b', **self.file_opt)

ただアイデアを与えるために...

于 2012-12-13T19:40:22.573 に答える