Я думаю, я понял это. Проблема в том, что переменная на самом деле устанавливается дважды с помощью ttk OptionMenu.
Взгляните на этот кусок кода из tkinter OptionMenu:
for v in values:
menu.add_command(label=v, command=_setit(variable, v, callback))
Добавляет кнопку в меню для каждого значения с помощью команды _setit
. Когда вызывается _setit
, он устанавливает переменную и другой обратный вызов, если предоставляется:
def __call__(self, *args):
self.__var.set(self.__value)
if self.__callback:
self.__callback(self.__value, *args)
Теперь посмотрите на этот кусок кода из ttk OptionMenu:
for val in values:
menu.add_radiobutton(label=val,
command=tkinter._setit(self._variable, val, self._callback),
variable=self._variable)
Вместо command
это добавляет radiobutton
в меню. Все радиокнопки «сгруппированы», связав их с одной и той же переменной. Поскольку у радиокнопок есть переменная, при нажатии одной из них для переменной устанавливается значение кнопки. Кроме того, добавляется та же команда, что и в tkinter OptionMenu. Как уже говорилось, это устанавливает переменную, а затем запускает другую команду обеспечивает. Как видите, теперь переменная обновляется дважды, один раз, потому что она связана с радиокнопкой, и еще раз, потому что она установлена в функции _setit
. Поскольку вы отслеживаете изменение переменной и переменная задается дважды, ваш код также выполняется дважды.
Поскольку переменная задается дважды из кода ttk, я думаю, что вы ничего не можете с этим поделать. Если вы не измените переменную из какой-либо другой части вашего кода, кроме как из OptionMenu, вы можете не отслеживать переменную, а вместо этого добавить свою функцию как command
в OptionMenu:
entry1 = ttk.OptionMenu(root, first, *Ore.keys(), command=_up_options)
P.S. это было введено с this commit после this bugreport .
Я предполагаю, что при добавлении variable=self._variable
команда должна была быть изменена на command=self._callback
.