Метод flash кнопки вызывает кратковременное изменение цвета виджета, но с помощью метода config так же просто можно динамически изменять и другие параметры внешнего вида виджетов, таких как кнопки, метки и текст,. Например, эффекта мигания можно добиться путем инвертирования цветов переднего и заднего плана элементов вручную, вызывая метод config в обработчиках, установленных методом after. Ради забавы в примере 9.28 приводится версия сценария, подающего звуковой сигнал, в которой сделан еще один шаг.
Пример 9.28. PP4E\Gui\Tour\alarm-hide.py
# стирает и отображает кнопку в обработчике,
from tkinter import * import alarm
class Alarm(alarm.Alarm): # измените обработчик таймера
def __init__(self, msecs=1000): # по умолчанию = 1 секунда
self.shown = False alarm.Alarm.__init__(self, msecs)
def repeater(self):
self.bell()
if self.shown:
self.stopper.pack_forget()
else:
self.stopper.pack()
self.shown = not self.shown
self.after(self.msecs, self.repeater)
if __name__ == ‘__main__’: Alarm(msecs=500).mainloop()
Если запустить этот сценарий, на экране появится то же самое окно, но теперь при каждом событии от таймера кнопка поочередно будет стираться и отображаться вновь. Метод pack_forget виджета стирает нарисованный элемент, а метод pack отображает его снова — методы grid_ forget и grid аналогичным образом скрывают и отображают виджеты в сетке. Метод pack_forget удобно использовать для динамического изменения графического интерфейса. Например, можно решить, какие компоненты должны отображаться в тот или иной момент времени, создавать виджеты заранее и отображать их только по мере надобности. В данном случае это просто значит, что пользователь должен щелкнуть на кнопке, пока она видна, иначе шум будет продолжаться.
Сценарий в примере 9.29 идет еще дальше. Здесь с помощью нескольких методов реализовано скрытие и появления всего окна:
• Чтобы скрыть и отобразить не какой-то отдельный виджет, а целое окно, можно воспользоваться методами withdraw и deiconify этого окна. Метод withdraw, используемый в примере 9.29, полностью сти
рает окно и его ярлык (если необходимо, чтобы ярлык окна оставался видимым, используйте метод iconify).
• Метод lift поднимает окно над всеми другими окнами или над определенным окном, переданным методу в виде аргумента. Этот метод также может также вызываться под именем tkraise, но не raise — его именем в Tk, потому что raise в языке Python является зарезервированным словом.
• Метод state возвращает или изменяет текущее состояние окна — он принимает значения normal, iconic, zoomed (на весь экран) и withdrawn.
Поэкспериментируйте с этими методами, чтобы понять, чем они отличаются. Их также можно использовать для динамического вывода предварительно созданных диалогов, однако практическая ценность этого приема невелика.
Пример 9.29. PP4E\Gui\Tour\alarm-withdraw.py
# то же самое, но скрывает и отображает окно целиком
from tkinter import * import alarm
class Alarm(alarm.Alarm):
def repeater(self):
self.bell()
if self.master.state() == ‘normal’:
self.master.withdraw()
else:
self.master.deiconify()
self.master.lift()
self.after(self.msecs, self.repeater)
if __name__ == ‘__main__’: Alarm().mainloop() # master = корневое окно Tk
# по умолчанию
Этот сценарий действует точно так же, за исключением того, что при подаче сигнала появляется или исчезает все окно — закрывать его надо тогда, когда оно видно. Реализацию обработчика, вызываемого по таймеру, можно разнообразить массой других эффектов. Будете ли вы добиваться, чтобы ваши кнопки и окна мигали и исчезали, зависит скорее от мнения пользователей, чем от возможностей библиотеки tkinter.
Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, I том, 2011