简体   繁体   中英

tkinter: Specifying arguments for a function that's called when you press a button

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)

You've probably spotted the hole in my program: print can't specify arguments. This renders the whole thing useless and faulty. Obviously, having something like

command=print("foo")

will call that function when the object is actually instantiated and make command the return value (if any) of that function call. (Not what I want)

So, how can I specify arguments in the above mentioned scenario, and avoid having to define seperate command functions for each of the buttons?

If you have at least python 2.6 (which I'm guessing you are since you use print in a function position) you can use functools.partial . It takes a function and any arguments to supply and returns a callable that will call the underlying function and add on any arguments passed to the final call. For example:

>>> 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

Your example could be done as

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"))

If you don't have 2.6, you can implement partial as:

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)))

A simple solution is to use lambda, which lets you create anonymous functions.

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"))

Another choice is to use functools.partial , which is explained a bit in this answer: https://stackoverflow.com/a/2297423/7432

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM