如何将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] 

希望这可以帮助!