5

Tkinterコールバックとして実行される関数から返されたオブジェクトを取得するにはどうすればよいですか?

import Tkinter as Tk
from functools import partial

def square(x):
    return x*x

root = Tk.Tk()
var = Tk.IntVar(root, value=0) #the variable the gets passed to the class call
menu = Tk.OptionMenu(root, var, *[0,1,2,3,4,5]) #a drop-down list to choose a value for the variable
menu.pack()
button = Tk.Button(root, text='click', command = partial(square,var.get())) #a button that calls the class
button.pack()
root.mainloop()

明らかに、これは単純化された例です。実際には、ボタンによって呼び出される関数はオブジェクトを返します。これは、以降の操作のためにメインのPython名前空間に保持されるオブジェクトのリストに追加したいと思います。

とにかく、ここでユーザーはGUIを使用して関数の引数を選択し、関数を実行するボタンを押すことができます。ただし、コールバックは戻り値を受け入れないため、関数の戻り値はエーテルに失われる運命にあるようです。globalこれは、の定義に醜いものを使用せずに克服できますsquare(x)か?

4

3 に答える 3

9

コールバックから値を「返す」という概念は、イベント駆動型プログラムのコンテキストでは意味がありません。コールバックはイベントの結果として呼び出されるため、値を返す場所がありません。

一般的な経験則として、コールバックはfunctools.partialまたはを使用するのではなく、常に関数を呼び出す必要がありますlambda。これらの2つは必要に応じて問題ありませんが、オブジェクト指向のコーディングスタイルを使用している場合、これらは不要であることが多く、必要以上に保守が難しいコードになります。

例えば:

def compute():
    value = var.get()
    result = square(value)
    list_of_results.append(result)

button = Tk.Button(root, text='click', command = compute)
...

これははるかに簡単になり、アプリケーションをクラスとして作成すると、グローバル変数を回避できます。

class App(...):
    ...
    def compute():
        ...
        result = self.square(self.var.get())
        self.results.append(result)
于 2012-08-10T18:55:47.307 に答える
7

6年遅れて申し訳ありませんが、最近、コードを乱雑にしたり保守したりすることなく、これを行うための良い方法を見つけました。これはDaveTheScientistが言ったこととほぼ同じですが、少し拡張したいと思います。通常、Tkinterでは、ボタンで関数を呼び出したい場合は、次のようにします。

exampleButton = Button(root, text = 'Example', command = someFunc)

someFuncこれは、ボタンが押されるたびに単に呼び出されます。ただし、この関数が引数を取る場合は、ラムダを使用して次のようなことを行う必要があります。

exampleButton = Button(root, text = 'Example', command = lambda: someFunc(arg1, arg2))

上記のコード行はsomeFunc、変数を実行してその関数の引数として使用しarg1ますarg2。さて、多くの場合、値を返すためにボタンによって実行される関数が必要になるプログラムでできることは、すべてのボタンによって呼び出される新しい関数を作成することです。

この関数は、ボタンで実行する関数を最初の引数として受け取り、その後、その関数の引数を取ります。

def buttonpress(function, *args):
    value = function(*args)

次に、ボタンを作成するときに、次のことを行います。

exampleButton = Button(root, text = 'Example', command = lambda: buttonpress( someFunc, arg1, arg2 ))

これにより、指定された関数(この場合はsomeFunc)が実行され、戻り値がvalue変数に格納されます。また、ボタンが実行する関数に必要な数の引数を使用できるという利点もあります。

于 2018-03-03T14:06:26.460 に答える
0

すべてをそのようにインライン化するのではなく、ボタンによって呼び出される実際の関数を作成するだけです。

button=Tk.Button(parent, text='click', command=someFxn)

def someFxn(): your code

次に、関数でvar.get()を呼び出し、計算を実行してから、値を使用して何かを実行します。

于 2012-08-10T18:02:01.737 に答える