#python #tkinter
#python #tkinter
Вопрос:
Я хочу проверить, изменил ли пользователь какие-либо значения в виджетах tkinter, а затем предложить сохранить эти значения или потерять изменения.
У многих приложений есть 3 кнопки в правом нижнем углу их рамки настроек OK
, Cancel
, и Apply
где Apply
отключено, пока не будет внесено изменение. Я имитирую эту функцию в своей программе.
Когда я использую tk.OptionMenu(command=function)
, по умолчанию он отправляет текущий пользовательский выбор в функцию, однако мне не нужно знать текущий выбор, потому что независимо от того, что это такое, я хочу предложить пользователю сохранить настройки.
Запуск программы приведет к следующей ошибке:
Ошибка типа: функция() принимает 0 позиционных аргументов, но был задан 1
Простым обходным решением, о котором я подумал, было бы присвоить произвольному параметру значение function()
like so:
def function(param=None):
value_change.status = True
Смотрите Пример кода для value_change.status
использования.
Однако PyCharm указывает, что param
это не используется, и помечает его как слабое предупреждение. Я не могу использовать переданное значение, поэтому я ничего не могу сделать, param
кроме как игнорировать его и предупреждение PyCharm. Технически здесь нет ничего плохого, но мне нравится видеть эту зеленую галочку в правом верхнем углу экрана, поэтому я придумал другое обходное решение:
def function(param=None):
value_change.status = True if param else False
Оба param=None
и if param else False
являются избыточными, поскольку они являются только заполнителями, чтобы код выполнялся плавно и не выдавал никаких предупреждений.
Другая проблема возникает, когда я хочу использовать function()
для других команд виджета, которые не передают аргументы, такие как tk.Checkbutton(command=function)
и я должен изменить свой код на следующие строки, что делает код еще более избыточным, чем раньше.
def function(param=True):
value_change.status = True if param else False
Есть ли способ не передавать аргумент через tk.OptionMenu(command=function)
?
Пример кода
import time
import tkinter as tk
from threading import Thread
def value_change():
value_change.count = 0
value_change.status = False
print('Has the user changed settings in the past 3 seconds?')
while value_change.status != 'exit':
if value_change.status:
value_change.count = 1
# Reset count if no change after 3 seconds
if value_change.count > 3:
value_change.count = 0
value_change.status = False
print(value_change.status)
time.sleep(1)
def function(param=True):
value_change.status = True if param else False
value_change.count = 0
gui = tk.Tk()
gui.geometry('100x100')
"""Setup OptionMenu"""
menu_options = ['var1', 'var2', 'var3']
menu_string = tk.StringVar()
menu_string.set(menu_options[0])
option_menu = tk.OptionMenu(gui, menu_string, *menu_options, command=function)
option_menu.pack()
"""Setup CheckButton"""
check_int = tk.IntVar()
check = tk.Checkbutton(gui, variable=check_int, command=function)
check.pack()
"""Turn On Thread and Run Program"""
Thread(target=value_change).start()
gui.mainloop()
"""Signal Threaded Function to Exit"""
value_change.status = 'exit'
Приведенный выше пример представляет собой минимальное воспроизведение, я не включил OK
Cancel
Apply
кнопки и их функции, поскольку они не нужны и только сделают код длинным.
Ответ №1:
Вы можете использовать lambda
:
option_menu = tk.OptionMenu(gui, menu_string, *menu_options, command=lambda v: function())
Комментарии:
1. Идеально! Большое спасибо