tkinter:为按钮点击时调用的函数指定参数

2 投票
2 回答
5608 浏览
提问于 2025-04-15 19:29
button1 = tkinter.Button(frame, text="Say hi", command=print)
button2 = tkinter.Button(frame, text="foo", command=print)
button3 = tkinter.Button(frame, text="bar", command=print)

你可能发现了我程序中的一个问题:print 不能指定参数。这让整个程序变得没用且有缺陷。显然,像这样的代码

command=print("foo")

会在对象真正被创建的时候调用那个函数,并将 command 设置为那个函数调用的返回值(如果有的话)。(这不是我想要的)

那么,在上述情况下,我该如何指定参数,并避免为每个按钮定义单独的 command 函数呢?

2 个回答

7

如果你至少有 Python 2.6(我猜你是因为你在函数里用到了 print),那么你可以使用 functools.partial。这个东西的作用是,它可以接收一个函数和一些参数,然后返回一个可以调用的东西。这个可调用的东西会在最后一次调用时,调用原来的函数,并把你传入的参数加上去。举个例子:

>>> from functools import partial
>>> def add(x,y): return x+y
>>> add2 = partial(add,2)
>>> add3 = partial(add,3)
>>> add2(3)
5
>>> add3(5)
8

你的例子可以这样做:

from functools import partial
button1 = tkinter.Button(frame, text="Say hi", command=partial(print,"hi"))
button2 = tkinter.Button(frame, text="foo", command=partial(print,"foo"))
button3 = tkinter.Button(frame, text="bar", command=partial(print,"bar"))

如果你没有 2.6 版本,你可以这样实现 partial:

def partial(fun, *args, **kwargs):
  def merge(d1,d2):
    r = dict(d1)
    r.update(d2)
    return r
  return lambda *a,**kw: fun(*(args+a),**(merge(kwargs,kw)))
2

一个简单的解决办法是使用lambda,它可以让你创建没有名字的函数。

button1 = tkinter.Button(frame, text="Say hi", command=lambda: print("Say hi")
button2 = tkinter.Button(frame, text="foo", command=lambda: print("foo"))
button3 = tkinter.Button(frame, text="bar", command=lambda: print("bar"))

另一个选择是使用 functools.partial,这个在这个回答中有稍微解释一下: https://stackoverflow.com/a/2297423/7432

撰写回答