Протоколы окна верхнего уровня

protokoly okna verhnego urovnya Экскурсия по tkinter, часть 1

Виджеты Tk и Toplevel экспортируют дополнительные методы и свойства, предназначенные для той роли, которую они играют на верхнем уровне, что иллюстрируется примером 8.5.

Пример 8.5. PP4E\Gui\Tour\toplevel2.py

Открывает три новых окна со стилями

метод destroy() закрывает одно окно, метод quit() закрывает все окна и завершает приложение (прерывает работу функции mainloop);

окна верхнего уровня имеют заголовки, значки, могут сворачиваться и восстанавливаться и поддерживают протокол событий wm;

приложение всегда имеет корневое окно, создаваемое по умолчанию или явно, вызовом конструктора Tk(); все окна верхнего уровня являются контейнерами, но они никогда не размещаются с помощью менеджера компоновки; объект Toplevel напоминает фрейм Frame, но в действительности является новым окном и может иметь собственное меню;

from tkinter import *

root = Tk() # explicit root

trees = [(‘The Larch!’, ‘light blue’),

(‘The Pine!’, ‘light green’),

(‘The Giant Redwood!’, ‘red’)]

for (tree, color) in trees:

win = Toplevel(root) # новое окно

win.title(‘Sing…’) # установка границ

win.protocol(‘WM_DELETE_WINDOW’, lambda:None) # игнорировать закрытие

win.iconbitmap(‘py-blue-trans-out.ico’) # вместо значка Tk

msg = Button(win, text=tree, command=win.destroy) # закрывает одно окно

msg.pack(expand=YES, fill=BOTH)

msg.config(padx=10, pady=10, bd=10, relief=RAISED)

msg.config(bg=’black’, fg=color, font=(‘times’, 30, ‘bold italic’))

root.title(‘Lumberjack demo’)

Label(root, text=’Main window’, width=30).pack()

Button(root, text=’Quit All’, command=root.quit).pack() # завершает программу root.mainloop()

Эта программа добавляет виджеты в корневое окно Tk, сразу выводит три окна Toplevel с прикрепленными к ним кнопками и использует специальные протоколы верхнего уровня. Если запустить этот пример, он создаст картинку, переданную в черно-белом изображении на рис. 8.4 (на мониторе текст кнопок отображается синим, зеленым и красным цветом).

Рис. 8.4. Три настроенных окна Toplevel

 

Здесь следует отметить несколько деталей, касающихся функционирования, которые станут более заметными, если вы запустите сценарий на своем компьютере:

Перехват закрытия: protocol

Этот сценарий перехватывает событие закрытия окна менеджера окон с помощью метода виджета верхнего уровня protocol, поэтому при нажатии кнопки X в правом верхнем углу какого-либо из трех окон Toplevel ничего не происходит. Строка WM_DELETE_WINDOW обозначает операцию закрытия. С помощью этого метода можно запретить закрытие окон, кроме как из создаваемых в сценарии виджетов. Создаваемая этим сценарием функция lambda: None лишь возвращает значение None и больше ничего не делает.

Закрытие одного окна (и его дочерних окон): destroy

При нажатии на большую черную кнопку в любом из трех дополнительных окон закрывается только это окно, потому что это действие вызывает метод destroy виджета. Остальные окна продолжают существовать, как это свойственно диалоговым окнам. Технически вызов этого метода приводит к уничтожению соответствующего виджета и всех остальных виджетов, для которых он является родителем. В случае окон под этим подразумевается все их содержимое. В случае более простых виджетов метод destroy уничтожает сам виджет.

Вследствие того, что окна Toplevel имеют родителя, эти их отношения могут иметь последствия при применении метода destroy. Уничтожение окна, даже первого корневого окна Tk, созданного автоматически или явно, — которое является родителем по умолчанию, — приводит к уничтожению всех его дочерних окон. Так как корневые окна Tk не имеют родителя, на них никак не действует уничтожение других окон. При этом уничтожение последнего (или единственного) корневого окна Tk приводит к завершению программы. Окна Toplevel всегда уничтожаются при уничтожении родителя, но их уничтожение никак не влияет на другие окна, для которых они не являются предками. Это делает их идеальными для создания диалогов. Технически виджет Toplevel может быть дочерним по отношению к любому виджету и автоматически будет уничтожен вместе с родителем, однако обычно они создаются как потомки окна Tk, созданного явно или автоматически.

Закрытие всех окон: quit

Чтобы закрыть сразу все окна и завершить приложение с графическим интерфейсом (в действительности — активный вызов mainloop), кнопка корневого окна вызывает метод quit. То есть нажатие кнопки в корневом окне завершает работу приложения. Метод quit немедленно завершает приложение в целом и закрывает все его окна. Он может быть вызван относительно любого виджета tkinter, а не только относительно окна верхнего уровня — этот метод имеется также у фреймов, кнопок и других виджетов. Дополнительные подробности о методах quit и destroy вы найдете в обсуждении метода bind и его события <Destroy> далее в этой главе.

Заголовки окон: title

В главе 7 говорилось о методе title виджетов окон верхнего уровня (Tk и Toplevel), позволяющем изменять текст, выводимый в области верхней кромки окна. В данном случае в качестве текста заголовка окна устанавливается строка Si…’, замещающая текст по умолчанию tk’.

Значки окон: iconbitmap

Метод iconbitmap изменяет значок окна верхнего уровня. Он принимает значок или файл с растровым изображением и использует его в качестве графического значка окна, когда оно сворачивается и открывается. Если в Windows передать имя файла с расширением .ico (в данном примере используется такой файл, находящийся в текущем каталоге), он заменит значок по умолчанию с красными буквами «Tk», который обычно появляется в левом верхнем углу окна, а также в панели задач Windows. На других платформах вам может потребоваться использовать иные соглашения о файлах со значками, если вызов этого метода в наших примерах не дает желаемого результата (или просто закомментируйте вызов этого метода, если он приводит к аварийному завершению сценариев) — значки обычно являются платформозависимой особенностью, работа с ними зависит от используемого менеджера окон.

Управление компоновкой

Окна верхнего уровня служат контейнерами для других виджетов, подобно отдельному фрейму Frame. Однако в отличие от фреймов, виджеты — окна верхнего уровня — сами не компонуются (и не размещаются каким-либо другим менеджером компоновки). Для встраивания виджетов этот сценарий передает свои окна в аргументах, определяющих родительское окно, конструкторам меток и кнопок.

Имеется также возможность определять максимальный размер окна (физические размеры экрана в виде кортежа [ширина, высота]) с помощью метода maxsize() и устанавливать начальные размеры окна с помощью высокоуровневого метода geometry(“ width x height + x + y “). На практике гораздо проще и удобнее позволить библиотеке tkinter (или вашим пользователям) самой устанавливать размер окон, тем не менее размер экрана может пригодиться при выборе масштаба отображения изображений (смотрите обсуждение PyPhoto в главе 11, например).

Кроме того, графические элементы окон верхнего уровня поддерживают другие типы протоколов, которые будут позднее использованы в данном обзоре:

Состояние

Методы iconify и withdraw объектов окон верхнего уровня позволяют сценариям сворачивать или удалять окна на лету; метод deiconify перерисовывает свернутое или удаленное окно. Метод state возвращает или изменяет состояние окна — допустимыми значениями, которые могут устанавливаться или возвращаться, являются: iconic, withdrawn, zoomed Windows: распахнутое на весь экран с помощью geometry или какого-либо другого метода) и normal (достаточно большого размера, чтобы вместить все содержимое). Методы lift и lower поднимают или опускают окно относительно других (метод lift является аналогом команды raise библиотеки Tk, которое является зарезервированным словом в языке Python). Их использование демонстрируется в сценариях будильника в конце главы 9.

Меню

Каждое окно верхнего уровня может иметь собственное меню — виджеты Tk и Toplevel принимают параметр menu, который используется для подключения горизонтальной строки меню с открывающимися списками элементов выбора. Эта строка меню выглядит соответствующим образом на каждой платформе, где выполняется сценарий. Меню будут изучаться в начале главы 9.

Большую часть методов окна верхнего уровня, используемых для взаимодействия с менеджером окон, можно также вызывать под именами с префиксом «wm_». Например, методы state и protocol можно также вызвать как wm_state и wm_protocol.

Обратите внимание, что в примере 8.3 при вызове конструктора Toplevel ему явно передается родительский виджет — корневое окно Tk (то есть Toplevel(root)). Окна Toplevel можно связывать с родительскими, как и любые другие виджеты, хотя зрительно они не встраиваются в родительские окна. Такой способ написания сценария имел целью избежать одной, на первый взгляд странной, особенности. Если бы окно создавалось так:

win = Toplevel() # новое окно

и корневое окно Tk при этом еще не существовало бы, этот вызов создал бы корневое окно Tk по умолчанию, которое стало бы родителем для окон Toplevel, как при всяком другом вызове графического элемента без передачи аргумента со ссылкой на родителя. Проблема в том, это делает принципиальным местоположение следующей строки:

root = Tk() # явное создание корня

Если поместить эту строку выше вызовов конструктора Toplevel, она создаст одно корневое окно, как и предполагается. Но если поставить эту строку ниже вызовов Toplevel, то tkinter создаст корневое окно Tk, которое будет отлично от созданного сценарием при явном вызове Tk. Это приведет к созданию двух корневых окон Tk, как в примере 8.4. Переместите вызов Tk под вызовы Toplevel, перезапустите сценарий, и вы увидите, что я имею в виду — вы получите четвертое, совершенно пустое окно! Чтобы избежать таких странностей, возьмите за правило создавать корневые окна Tk в начале сценариев и явным образом.

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

theframe.master.title(‘Spam demo’) # master является окном-контейнером

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

Для виджетов верхнего уровня существуют другие инструменты, некоторые из которых могут не встретиться в этой книге. Например, в менеджерах окон Unix можно также устанавливать имя значка окна (iconname). Поскольку некоторые параметры значков можно применять только в сценариях, выполняемых в Unix, подробности, касающиеся этой темы, смотрите в других ресурсах по библиотекам Tk и tkinter. А сейчас нас ожидает следующая запланированная остановка в нашей экскурсии, где будет рассказано об одном из наиболее частых применений окон верхнего уровня.

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

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