Так зачем здесь нужны переменные? Первое, у переключателей нет метода «get», который позволил бы получить значение выбора. Еще более важно то, что в группах переключателей именно параметры value и variable обслуживают режим выбора единственного варианта. Вообще, работа переключателей обеспечивается тем, что вся группа ассоциируется с одной и той же переменной tkinter и при этом все переключатели имеют различные значения. Чтобы до конца разобраться в этом, нужны еще некоторые сведения о том, как взаимодействуют переключатели и переменные.
Как мы уже видели, при изменении состояния виджета изменяется ассоциируемая с ним переменная tkinter, и наоборот. Но также верно и то, что любое изменение переменной автоматически изменяет каждый виджет, с которым она связана. При работе с переключателями щелчок на одном из них устанавливает значение совместно используемой переменной, которая, в свою очередь, оказывает воздействие на другие переключатели, ассоциированные с этой переменной. При условии, что все переключатели имеют различные значения, это вызывает ожидаемый эффект. Когда в результате щелчка на переключателе значение совместно используемой переменной изменяется на значение выбранного переключателя, все остальные переключатели оказываются невыбран- ными, потому что значение переменной не совпадает с их значениями.
Это правило действует в обоих направлениях: когда пользователь выбирает переключатель — он неявно изменяет значение совместно используемой переменной; когда сценарий изменяет значение переменной, — он изменяет состояние переключателей. Например, когда сценарий в примере 8.25 на этапе инициализации присваивает совместно используемой переменной последнее значение последнего переключателя (вызовом self.var.set), он выбирает последний переключатель, а остальные автоматически становятся невыбранными. В результате изначально будет выбран только один переключатель. Если бы в переменную была записана строка, не являющаяся именем какого-либо демонстрационного диалога (например, ‘ ‘), все переключатели при запуске оказались бы невыбранными.
Это довольно тонкий волновой эффект, но его будет проще понять, представив картину с другой стороны: если в группе переключателей, связанных с одной и той же переменной, назначить нескольким переключателям одно и то же значение, то при щелчке на любом из них все они будут автоматически выбраны. Рассмотрим пример 8.26 и рис. 8.29. При запуске сценария не выбран ни один переключатель (так как совместно используемая переменная инициализирована значением, не соответствующим ни одному из значений переключателей), но поскольку переключатели 0, 3, 6 и 9 — имеют значение 0 (остаток от деления на 3), при выборе любого из них выбираются они все.
Рис. 8.29. Переключатели испортились?
Пример 8.26. PP4E\Gui\Tour\demo—radio—multi.py
# посмотрите, что произойдет, если несколько переключателей
# будут иметь одно и то же значение
from tkinter import * root = Tk() var = StringVar() for i in range(10): rad = Radiobutton(root, text=str(i), variable=var, value=str(i % 3)) rad.pack(side=LEFT)
var.set(‘ ‘) # все переключатели сделать невыбранными
root.mainloop()
Если теперь щелкнуть на любом из переключателей 1, 4 или 7, будут выбраны все три, а предыдущие выбранные окажутся сброшенными (их значение не равно «1»). Обычно это не то, что требуется, — переключатели как правило используются для представления групп с возможностью выбора единственного варианта (возможность выбора сразу нескольких вариантов реализуется с помощью флажков). Если вы хотите, чтобы переключатели действовали, как им положено, следите за тем, чтобы всем переключателям была назначена одна и та же переменная, но разные значения. Например, в сценарии demoRadio имя демонстрационного диалога дает естественное уникальное значение для каждой кнопки.
Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, I том, 2011