Снова о создании модальных окон

snova o sozdanii modalnyh okon Экскурсия по tkinter, часть 1

Далее мы увидим, как создавать аналогичные структуры форм с помощью менеджера компоновки grid, где вместо фреймов размещение виджетов выполняется по номерам рядов и столбцов. Но сейчас, реализовав структуру формы, посмотрим, как применять технологию создания модальных диалогов к более сложным формам.

Сценарий в примере 8.19, используя функции makeform и fetch из предыдущего примера, создает форму и выводит ее содержимое подобно тому, как это делалось раньше. Но теперь поля ввода прикрепляются к новому всплывающему окну Toplevel, создаваемому по требованию и содержащему кнопку OK, генерирующую событие уничтожения окна. Как мы уже знаем, метод wait_window влечет приостановку программы, пока окно не будет закрыто.

Пример 8.19. PP4E\Gui\Tour\entry2-modal.py

#  создает модальный диалог с формой;

#  данные должны извлекаться до уничтожения окна с полями ввода

from tkinter import *

from entry2 import makeform, fetch, fields

def show(entries, popup): fetch(entries) # извлечь данные перед уничтожением окна!

popup.destroy() # если инструкции поменять местами, сценарий

# будет возбуждать исключение

def ask():

popup = Toplevel() # отобразить форму в виде модального диалога

ents = makeform(popup, fields)

Button(popup, text=’OK’, command=(lambda: show(ents, popup))).pack() popup.grab_set() popup.focus_set() popup.wait_window() # ждать закрытия окна

root = Tk()

Button(root, text=’Dialog’, command=ask).pack()

root.mainloop()

Если нажать кнопку в главном окне, сценарий создаст окно диалога с формой, блокирующее остальное приложение, изображенное на рис. 8.25.

В реализации этого модального диалога таится малозаметная опасность: поскольку он извлекает данные, вводимые пользователем, из виджетов Entry, встроенных во всплывающее окно, эти данные необходимо получить прежде чем окно будет уничтожено в обработчике события нажатия кнопки OK. Оказывается, что вызов destroy действительно уничтожает все виджеты окна — попытка получить значение из уничтоженного виджета Entry не только не действует, но и порождает исключение с выводом трассировочной информации и сообщения об ошибке в окне консоли — попробуйте изменить порядок команд в функции show, и вы убедитесь в этом сами.

Рис. 8.25. Окна, создаваемые сценарием entry2-modal entry3-modal)

 

Чтобы избежать этой проблемы, нужно следить за тем, чтобы выборка значений осуществлялась перед уничтожением, или использовать переменные tkinter, являющиеся предметом обсуждения следующего раздела.

Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, I том, 2011

Оцените статью
Секреты программирования
Добавить комментарий