tkinter: указание аргументов для функции, которая вызывается при нажатии кнопки - PullRequest
2 голосов
/ 19 февраля 2010
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 ]

6 голосов
/ 19 февраля 2010

Если у вас есть по крайней мере 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, вы можете реализовать частичное как:

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 голосов
/ 19 февраля 2010

Простым решением является использование лямбды, которая позволяет создавать анонимные функции.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...