Вы можете сохранить данные в делегате приложения, чтобы получить доступ к ним через контроллеры представлений в своем приложении. Все, что вам нужно сделать, это создать общий экземпляр делегата приложения
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
. Для примера
, если вы объявите NSArray object *arrayXYZ
, вы можете получить к нему доступ в любом контроллере представления appDelegate.arrayXYZ
Вам нужно создать функцию без параметров, которые вы можете использовать в качестве команды:
b = Button(admin, text='as', command=lambda: button('hey'))
См. раздел «Передача аргументов в обратные вызовы» в этом документе .
Предположим, что у меня есть GUI:
import tkinter as tk
root = tk.Tk()
btn = tk.Button(root, text="Press")
btn.pack()
root.mainloop()
См., когда btn
нажата, вызывает свою собственную функцию , которая очень похожа на button_press_handle
в следующем примере:
def button_press_handle(callback=None):
if callback:
callback() # Where exactly the method assigned to btn['command'] is being callled
с:
button_press_handle(btn['command'])
Вы может просто предположить, что параметр command
должен быть установлен как ссылка на метод, который мы хотим назвать, аналогичный callback
в button_press_handle
.
Без аргументов
Итак, если я хотел print
что-то при нажатии кнопки I необходимо установить:
btn['command'] = print # default to print is new line
Обратите внимание на недостаток в ()
с помощью метода print
, который опущен в том смысле, что: " Это имя метода, которое я хочу, чтобы вы вызывали при нажатии, но не вызываете его именно в этот момент ». Однако я не передал никаких аргументов для print
, поэтому он печатал все, что он печатает, когда без аргументов.
W ith Аргумент (ы)
Теперь Если бы я хотел также передать аргументы методу, который я хочу называть при нажатии кнопки, я мог бы использовать анонимные функции, которые могут быть созданы с помощью оператора lambda , в этом случае для встроенного метода print
, например:
btn['command'] = lambda arg1="Hello", arg2=" ", arg3="World!" : print(arg1 + arg2 + arg3)
Без Аргументы
Вы также можете добиться этого с помощью оператора lambda
, но он считается плохим и поэтому я не буду включать его здесь. Хорошей практикой является определение отдельного метода multiple_methods
, который вызывает нужные методы, а затем устанавливает его как ответ на нажатие кнопки:
def multiple_methods():
print("Vicariously") # the first inner callback
print("I") # another inner callback
С Аргумент (s)
Чтобы передать аргумент (ы) методу, который вызывает другие методы, снова используйте инструкцию lambda
, но сначала:
def multiple_methods(*args, **kwargs):
print(args[0]) # the first inner callback
print(kwargs['opt1']) # another inner callback
, а затем установите :
btn['command'] = lambda arg="live", kw="as the" : a_new_method(arg, opt1=kw)
Также обратите внимание, что callback
не может реально return
, потому что он только вызывается внутри button_press_handle
] с callback()
в отличие от return callback()
. Это делает return
, но не вне этой функции. Таким образом, вам лучше изменить объект (ы), которые доступны в текущей области.
Ниже приведен вызов метода, который меняет текст btn
при каждом нажатии кнопки:
import tkinter as tk
i = 0
def text_mod():
global i, btn # btn can be omitted but not sure if should be
txt = ("Vicariously", "I", "live", "as", "the", "whole", "world", "dies")
btn['text'] = txt[i] # the global object that is modified
i = (i + 1) % len(txt) # another global object that gets modified
root = tk.Tk()
btn = tk.Button(root, text="My Button")
btn['command'] = text_mod
btn.pack(fill='both', expand=True)
root.mainloop()
button('hey')
вызывает функцию, а не устанавливает ее как обратный вызов.
Не используйте какое-либо ключевое слово или аргумент в качестве ввода или скобки для вашей функции. Это очень простое решение:)
Параметр command
ссылается на функцию, которая является причудливым способом сказать, что вам нужно передать ей имя функции. Когда вы выполняете button('hey')
, вы вызываете функцию button
, , и результат этого присваивается опции command
.
Чтобы передать ссылку, вы должны использовать только имя, не используя круглые скобки или аргументы. Например:
b = Button(... command = button)
Если вы хотите передать такой параметр, как «hey», вы должны использовать небольшой дополнительный код:
button
, lambda
, чтобы создать то, что называется анонимной функцией . Во всех отношениях это функция, за исключением того, что у нее нет имени. Когда вы вызываете команду lambda
, она возвращает ссылку на созданную функцию, что означает, что она может использоваться для значения параметра command
для кнопки. Для меня lambda
является самым простым, поскольку он не требует каких-либо дополнительных импортов, таких как functools.partial
, хотя некоторые люди думают, что functools.partial
легче понять.
Чтобы создать функцию лямбда, которая вызывает вашу функцию button
с аргументом, вы сделали бы что-то вроде этого:
lambda: button('hey')
Вы получаете функцию, функционально эквивалентную:
def some_name():
button('hey')
Как я уже говорил ранее, lambda
возвращает ссылку на эту безымянную функцию. Поскольку ссылка означает, что вариант command
предполагает, что вы можете использовать lambda
направление при создании кнопки:
b = Button(... command = lambda: button('hey'))
На этом сайте есть вопрос, который содержит много интересных комментариев о лямбда , в целом. См. Вопрос Почему Python lambdas полезны? . В этом же обсуждении был ответ, в котором показано, как использовать лямбда в петле , когда вам нужно передать переменную в обратный вызов.
Наконец, см. раздел Tkinter Callbacks на effbot.org для хорошего учебника. Охват лямбда довольно скудный, но информация там может быть полезной.