Предположим, я Button
сделал следующее с Tkinter в Python:
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)
Метод action
вызывается, когда я нажимаю кнопку, но что, если я хочу передать некоторые аргументы методу action
?
Я пытался с помощью следующего кода:
button = Tk.Button(master=frame, text='press', command=action(someNumber))
Это сразу вызывает метод, и нажатие кнопки ничего не делает.
Ответы:
Лично я предпочитаю использовать
lambdas
в таком сценарии, потому что, по моему мнению , он понятнее и проще, а также не заставляет вас писать множество методов-обёрток, если у вас нет контроля над вызываемым методом, но это, безусловно, дело вкуса.Вот как вы бы сделали это с лямбдой (обратите внимание, что в функциональном модуле также есть некоторая реализация каррирования), так что вы также можете использовать это):
источник
partial
работает в этом случае."This just invokes the method immediately, and pressing the button does nothing"
?callback=lambda x=x: f(x)
как и вfs = [lambda x=x: x*2 for x in range(5)] ; print [f() for f in fs]
Это также можно сделать с помощью
partial
стандартных библиотечных функций , например:источник
button = Tk.Button(master=frame, text='press', command=partial(action, arg))
action_with_args = partial(action, arg1, arg2... argN)
Пример GUI:
Допустим, у меня есть графический интерфейс:
Что происходит при нажатии кнопки
Посмотрите, что при
btn
нажатии он вызывает свою собственную функцию, которая очень похожаbutton_press_handle
на следующий пример:с участием:
Вы можете просто подумать, что
command
опция должна быть установлена как ссылка на метод, который мы хотим вызвать, какcallback
вbutton_press_handle
.Вызов метода ( обратный вызов ) при нажатии кнопки
Без аргументов
Поэтому, если я хочу
print
что-то, когда кнопка нажата, мне нужно установить:Обратите особое внимание на отсутствие в
()
сprint
методом , который опускается в том смысле , что: «Это имя метода, который я хочу вам позвонить , когда нажата , но не называйте это как раз этот самый момент.» Тем не менее, я не передавал никаких аргументов,print
поэтому он печатал все, что печатает, когда вызывается без аргументов.С аргументом (ами)
Теперь, если бы я также хотел передать аргументы методу, который я хочу вызывать при нажатии кнопки, я мог бы использовать анонимные функции, которые могут быть созданы с помощью оператора lambda , в данном случае для
print
встроенного метода, как показано ниже :Вызов нескольких методов при нажатии кнопки
Без аргументов
Вы также можете добиться этого, используя
lambda
утверждение, но это считается плохой практикой, и поэтому я не буду его здесь включать. Хорошей практикой является определение отдельного метода,multiple_methods
который вызывает требуемые методы, а затем устанавливает его в качестве обратного вызова для нажатия кнопки:С аргументом (ами)
Чтобы передать аргумент (ы) методу, который вызывает другие методы, снова используйте
lambda
оператор, но сначала:и затем установите:
Возврат объекта (ов) из обратного вызова
Также обратите внимание , что в дальнейшем
callback
может на самом деле неreturn
потому , что это только называется внутриbutton_press_handle
сcallback()
в противоположностьreturn callback()
. Это делает,return
но не где-нибудь за пределами этой функции. Таким образом, вы должны скорее изменить объект (ы), которые доступны в текущей области.Завершите пример с глобальной модификацией объектов
Ниже приведен пример вызова метода, который изменяет
btn
текст при каждом нажатии кнопки:Зеркало
источник
Способность Python предоставлять значения по умолчанию для аргументов функции дает нам выход.
См .: http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/extra-args.html.
Для большего количества кнопок вы можете создать функцию, которая возвращает функцию:
источник
myX
иmyY
работает отлично, большое спасибо.Опираясь на ответ Мэтта Томпсона: класс можно сделать вызываемым, чтобы его можно было использовать вместо функции:
источник
Причина, по которой он вызывает метод немедленно и нажатие кнопки ничего не делает, заключается в том, что
action(somenumber)
вычисляется и его возвращаемое значение приписывается команде для кнопки. Таким образом, если выaction
печатаете что-то, чтобы сказать вам, что оно запустилось и вернулосьNone
, вы просто бежите,action
чтобы оценить его возвращаемое значение и получитьNone
команду для кнопки.Чтобы иметь кнопки для вызова функций с разными аргументами, вы можете использовать глобальные переменные, хотя я не могу рекомендовать это:
Я хотел бы создать объект,
class
чьи объекты будут содержать все необходимые переменные и методы для их изменения по мере необходимости:источник
Я считаю, что это нужно исправить
источник
Лучше всего использовать лямбду следующим образом:
источник
Я очень поздно, но вот очень простой способ сделать это.
Вы просто заключаете функцию, которую хотите использовать, в другую функцию и вызываете вторую функцию нажатием кнопки.
источник
var1
иvar2
в основной модуль, вы можете вообще пропуститьfunction1
и вставитьprint
операторfunction2
. Вы ссылаетесь на другие ситуации, которые я не понимаю?Лямбды все хорошо, но вы также можете попробовать это (что работает в цикле for кстати):
Это работает, потому что, когда привязка установлена, нажатие клавиши передает событие в качестве аргумента. Затем вы можете вызвать атрибуты события, например,
event.char
получить «1» или «ВВЕРХ». Если вам нужен аргумент или несколько аргументов, отличных от атрибутов события. просто создайте словарь для их хранения.источник
Я тоже сталкивался с этой проблемой и раньше. Вы можете просто использовать лямбду:
источник
Используйте лямбду для передачи входных данных в командную функцию, если вам нужно выполнить больше действий, например, вот так (я попытался сделать это универсальным, поэтому просто адаптируйтесь):
Это передаст информацию о событии функции кнопки. Там может быть больше Pythonesque способов написания этого, но это работает для меня.
источник
JasonPy - несколько вещей ...
если вы вставите кнопку в цикл, она будет создаваться снова и снова ... что, вероятно, не то, что вам нужно. (Может быть это)...
Причина, по которой он всегда получает последний индекс, заключается в том, что лямбда-события запускаются при нажатии на них, а не при запуске программы. Я не уверен на 100%, что вы делаете, но, возможно, попробуйте сохранить значение, когда оно будет сделано, затем вызовите его позже с помощью лямбда-кнопки.
Например: (не используйте этот код, просто пример)
тогда ты можешь сказать ....
надеюсь это поможет!
источник
Один из простых способов было бы настроить
button
сlambda
как следующий синтаксис:источник
Для потомков: вы также можете использовать классы для достижения чего-то похожего. Например:
Затем кнопка может быть просто создана:
Такой подход также позволяет изменять аргументы функции И.Е. настройки
instance1.x = 3
.источник
Вам нужно использовать
lambda:
источник
Используйте лямбду
вывод:
источник