web-dev-qa-db-ja.com

関数をウィジェットに引数でバインドするTkinter

Tkinterフレームとそれに接続されたボタンがあります:

from tkinter import *

def Rand_func(a,b,c,effects):
    print (a+b+c)

root=Tk()
frame=Frame(root)
frame.bind("<Return>",lambda a=10, b=20, c=30: Rand_func(a,b,c))
frame.pack()

button=Button(frame, text="click me", command=lambda a=1,b=2,c=3,eff=None:Rand_func(a,b,c))
button.pack()

root.mainloop()

ユーザーがEnterキーを押したときと、ボタンを押したときと同じ機能を実行したいと思います。残念ながら、上記のコードではフレームバインディングでエラーが発生します。誰かがこの問題の解決策を知っていますか?

12
Serban Razvan

bindでバインディングを作成すると、Tkinterはイベントに関する情報を含む引数を自動的に追加します。 Rand_func定義またはそれを呼び出す方法のいずれかで、それを説明する必要があります。

command属性を使用する場合、この引数はnot含まれます。それぞれの場合に関数を呼び出す方法、または関数がそのパラメーターを解釈する方法のいずれかで、この余分な引数を考慮するように注意する必要があります。

バインディングでlambdaを使用して、bindコマンドを使用する場合にのみ追加のイベントを受け入れ、最終コマンドには渡さない1つのソリューションを次に示します。

import tkinter as tk

class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.frame = tk.Frame(self)
        self.frame.pack()
        self.button = tk.Button(self.frame, text="click me",
                             command=lambda a=1, b=2, c=3: 
                                self.Rand_func(a, b, c))
        self.button.pack()
        self.frame.bind("<Return>", 
                        lambda event, a=10, b=20, c=30: 
                            self.Rand_func(a, b, c))
        # make sure the frame has focus so the binding will work
        self.frame.focus_set()

    def Rand_func(self, a, b, c):
        print "self:", self, "a:", a, "b:", b, "c:", c
        print (a+b+c)

app = SampleApp()
app.mainloop()

そうは言っても、フレームにバインドすることが正しいことであることはめったにありません。通常、フレームにはキーボードフォーカスがなく、フォーカスがない限り、バインディングは起動しません。グローバルバインディングを設定する場合は、「all」バインディングタグ( bind_all メソッドを使用)またはトップレベルウィジェットにバインドする必要があります。

17
Bryan Oakley

どうですか:

import tkinter as tk


def Rand_func(eff=None, a=1, b=2, c=3):
    print(a + b + c)

root = tk.Tk()
root.bind("<Return>", lambda eff: Rand_func(eff, a=10, b=20, c=30))

frame = tk.Frame(root)
frame.pack()

button = tk.Button(frame, text="click me",
                   command=lambda: Rand_func(None, 1, 2, 3))
button.pack()

root.mainloop()
2
unutbu