Другие способы реализации модальности

drugie sposoby realizacii modalnosti Экскурсия по tkinter, часть 1

Модальные диалоги обычно реализуются путем создания нового всплывающего окна и ожидания в нем события destroy, как в этом примере. Но существуют и другие схемы. Например, можно создать диалоговые окна заранее, и по мере необходимости показывать или скрывать их с помощью методов deiconify и withdraw окна верхнего уровня (подробности смотрите в сценариях раздела главы 9). С учетом того, что в настоящее время скорость выполнения такова, что создание окон происходит практически мгновенно, такой способ встречается значительно реже, чем создание окон с нуля и уничтожение их при каждом взаимодействии.

Можно также реализовать состояние модальности путем ожидания изменения значения переменной tkinter, а не уничтожения окна. Подробности смотрите в последующем обсуждении переменных tkinter в данной главе (они являются объектами классов, а не обычными переменными Python) и метода wait_variable в конце главы 9. В этой схеме обработчик события долгоживущего диалогового окна может подать сигнал об изменении состояния ожидающей головной программе без необходимости уничтожения диалогового окна.

Наконец, если вызвать метод mainloop рекурсивно, возврат из вызова произойдет только после выполнения метода quit виджета. Метод quit прекращает выполнение функции mainloop и потому обычно завершает выполнение программы с графическим интерфейсом. Но если был произведен рекурсивный вызов mainloop, метод quit просто завершит его. Благодаря этому модальные диалоги можно реализовать без обращения к методу ожидания. Так, сценарий в примере 8.14 работает аналогично dlgcustom в модальном режиме.

Пример 8.14. PP4E\Gui\Tour\dlg-recursive.py

from tkinter import *

def dialog():

win = Toplevel() # создать новое окно

Label(win, text=’Hard drive reformatted!’).pack() # добавить виджеты

Button(win, text=’OK’, command=win.quit).pack() # установить обрк quit win.protocol(‘WM_DELETE_WINDOW’, win.quit) # завершить и при # закрытии окна!

win.focus_set() # принять фокус ввода,

win.grab_set() # запретить доступ к др. окнам, пока открыт диалог

win.mainloop() # и запустить вложенный цикл обр. событий для ожидания win.destroy()

print(‘dialog exit’)

root = Tk()

Button(root, text=’popup’, command=dialog).pack() root.mainloop()

Выбирая этот путь, нужно вместо метода destroy вызывать в обработчиках событий метод quit (destroy не завершает функцию mainloop) и обеспечить вызов quit кнопкой закрытия окна с помощью метода protocol (иначе не будет завершаться рекурсивный вызов mainloop, что приведет к генерации странных сообщений об ошибках при окончательном выходе из программы). Из-за этой дополнительной сложности более удобным может оказаться использование wait_window или wait_variable, а не рекурсивных вызовов mainloop.

Как строить диалоги в виде форм с метками и полями ввода, мы увидим далее в этой главе, познакомившись с элементом Entry, и еще раз — при изучении менеджера grid в главе 9. Другие примеры пользовательских диалогов можно найти в демонстрационных приложениях ShellGui (глава 10), PyMailGui (глава 14), PyCalc (глава 19) и немодальном form. py (глава 12). А сейчас мы перейдем к более глубокому изучению событий, что несомненно пригодится на следующих этапах нашего турне.

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

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