При использовании обратного вызова в вызове trace
, callback
должен иметь возможность принимать 3 аргумента со стороны "tkinter". Вы можете изменить его так, чтобы он принимал ваши собственные аргументы, если вы используете sh, но он должен принять как минимум 3 от tkinter.
Чтобы увидеть, что это за аргументы, мы можем проверить документацию или провести быструю проверку по приведенному ниже примеру:
import tkinter as tk
def swap_images(*args):
print(f"I was passed {len(args)} arguments")
for n, arg in enumerate(args):
print(f"Arg {n}: {arg}")
root = tk.Tk()
mode = tk.StringVar(master=root, value="Hello", name="I'm the mode var!")
mode_entry = tk.Entry(master=root, textvariable=mode)
mode_entry.pack()
mode.trace("w", lambda *args: swap_images(*args))
root.mainloop()
Вывод из swap_images
функция (при изменении записи):
I was passed 3 arguments
Arg 0: I'm the mode var!
Arg 1:
Arg 2: w
Мы легко видим, что первый аргумент - это внутреннее имя переменной, а третий - выполняемая операция (w
riting).
Этого, наряду с этим упоминанием из документации, которую я связал выше, достаточно, чтобы выяснить, что является вторым аргументом:
Когда трассировка срабатывает, три аргумента добавляются к commandPrefix так что фактическая команда выглядит следующим образом:
commandPrefix name1 name2 op
name1
и name2
дают имя (имена) для доступ к переменной: если переменная является скаляром, то name1
дает имя переменной, а name2
- пустая строка; если переменная является элементом массива, то name1
дает имя массива, а name2
дает индекс в массиве; если удаляется весь массив и трасса была зарегистрирована в общем массиве, а не в одном элементе, то name1
дает имя массива, а name2
- пустое строка. name1
и name2
не обязательно совпадают с именем, используемым в команде переменной переменной: команда upvar позволяет процедуре ссылаться на переменную под другим именем.
op
указывает, какая операция выполняется с переменной, и является одной из операций чтения, записи или сброса, как определено выше.
Так что это значит для вас?
Исправить несложно - вам нужно изменить способ настройки трассировки, чтобы лямбда принимала дополнительные аргументы. Вам не нужно их использовать, и вам даже не нужно передавать их в функцию, которую вы вызываете внутри лямбды ... Но лямбда должна иметь возможность их принимать.
Изменить
mode.trace("w", lambda: swapimages(mode.get()))
до
mode.trace("w", lambda *args: swapimages(mode.get()))
Как я уже сказал, вы можете «выбросить» args
, не передавая его функции внутри вашей лямбды.