如何将parameter passing给Tkinter中的Button命令?
假设我在Python中使用了Tkinter中的以下Button
:
import Tkinter as Tk win = Tk.Toplevel() frame = Tk.Frame(master=win).grid(row=1, column=1) button = Tk.Button(master=frame, text='press', command=action)
当我按下button时会调用该方法的action
,但是如果我想将一些parameter passing给方法action
呢?
我已经尝试了以下代码:
button = Tk.Button(master=frame, text='press', command=action(someNumber))
这只是立即调用方法,按下button什么也不做。
我个人更喜欢在这样的情况下使用lambdas
,因为它更清晰,更简单,如果你不能控制被调用的方法,也不会强制你写很多的包装方法,但这当然是一个口味问题。
这就是你如何做一个lambda(注意,也有一些实现在function模块中的currying,所以你也可以使用它):
button = Tk.Button(master=frame, text='press', command= lambda: action(someNumber))
这也可以通过使用标准库functools中的 partial
来完成,如下所示:
from functools import partial #(...) action_with_arg = partial(action, arg) button = Tk.Button(master=frame, text='press', command=action_with_arg)
Python为函数参数提供默认值的能力给了我们一个出路。
def fce(x=myX, y=myY): myFunction(x,y) button = Tk.Button(mainWin, text='press', command=fce)
请参阅: http : //infohost.nmt.edu/tcc/help/pubs/tkinter/web/extra-args.html
对于更多的button,你可以创build一个函数返回一个函数:
def fce(myX, myY): def wrapper(x=myX, y=myY): pass pass pass return x+y return wrapper button1 = Tk.Button(mainWin, text='press 1', command=fce(1,2)) button2 = Tk.Button(mainWin, text='press 2', command=fce(3,4)) button3 = Tk.Button(mainWin, text='press 3', command=fce(9,8))
它立即调用该方法并按下该button的原因是该action(somenumber)
被计算并且其返回值被归为该button的命令。 因此,如果action
输出的内容告诉你它已经运行并且返回None
,那么你只需要运行action
来计算它的返回值,并且给出None
作为button的命令。
要使用不同参数调用函数的button,可以使用全局variables,尽pipe我不能推荐它:
import Tkinter as Tk frame = Tk.Frame(width=5, height=2, bd=1, relief=Tk.SUNKEN) frame.grid(row=2,column=2) frame.pack(fill=Tk.X, padx=5, pady=5) def action(): global output global variable output.insert(Tk.END,variable.get()) button = Tk.Button(master=frame, text='press', command=action) button.pack() variable = Tk.Entry(master=frame) variable.pack() output = Tk.Text(master=frame) output.pack() if __name__ == '__main__': Tk.mainloop()
我会做的是做一个class
其对象将包含所需的每个variables和方法来根据需要更改这些variables:
import Tkinter as Tk class Window: def __init__(self): self.frame = Tk.Frame(width=5, height=2, bd=1, relief=Tk.SUNKEN) self.frame.grid(row=2,column=2) self.frame.pack(fill=Tk.X, padx=5, pady=5) self.button = Tk.Button(master=self.frame, text='press', command=self.action) self.button.pack() self.variable = Tk.Entry(master=self.frame) self.variable.pack() self.output = Tk.Text(master=self.frame) self.output.pack() def action(self): self.output.insert(Tk.END,self.variable.get()) if __name__ == '__main__': window = Window() Tk.mainloop()
如果你有更多的行动来执行,使用lambda将条目数据传递给命令函数,就像这样(我试图使它通用,所以只适应):
event1 = Entry(master) button1 = Button(master, text="OK", command=lambda: test_event(event1.get())) def test_event(event_text): if not event_text: print("Nothing entered") else: print(str(event_text)) # do stuff
这将把事件中的信息传递给buttonfunction。 可能有更多Pythonesque的方式来写这个,但它对我有用。
JasonPy – 几件事…
如果你在一个循环中粘贴一个button,它会一遍又一遍地被创build……这可能不是你想要的。 (也许是)…
它总是得到最后一个索引的原因是当你点击它们时运行的lambda事件 – 而不是程序启动时。 我不能确定100%你在做什么,但可能试着存储它的值,然后用lambdabutton调用它。
例如:(不要使用这个代码,只是一个例子)
for entry in stuff_that_is_happening: value_store[entry] = stuff_that_is_happening
那么你可以说….
button... command: lambda: value_store[1]
希望这可以帮助!