Наиболее важным нововведением в этом примере является использование фреймов: виджеты Frame служат просто контейнерами для других виджетов, благодаря чему возникает представление о графических интерфейсах как об иерархиях, или деревьях виджетов. Здесь роль охватывающего окна для трех других элементов играет виджет win. Однако в целом, прикрепляя виджеты к фреймам, а фреймы к другим фреймам, можно строить графические интерфейсы с произвольной структурой. Просто поделите графический интерфейс на ряд прямоугольников уменьшающегося размера, реализуйте каждый из них как Frame и прикрепите к фреймам простые виджеты.
В данном сценарии, когда виджет win передается в первом аргументе конструкторам Label и Button, библиотека tkinter прикрепляет их к виджету Frame (они становятся дочерними для win). Сам объект win по умолчанию прикрепляется к окну верхнего уровня, потому что конструктору Frame не был передан родитель. Когда мы предлагаем виджету win начать выполнение (вызывая метод mainloop), библиотека tkinter отображает все графические элементы в построенном нами дереве.
Три дочерних виджета также позволяют указывать параметры pack: аргументы side говорят о том, к какой части содержащего их фрейма (то есть win) должен быть прикреплен новый виджет. Метка подвешивается к верхнему краю, а кнопки прикрепляются к боковым сторонам. TOP, LEFT и RIGHT являются строковыми переменными с предварительно присвоенными значениями, которые импортируются из tkinter. Размещение виджетов происходит немного сложнее, чем простое указание сторон, к которым они прикрепляются, но чтобы узнать почему, придется сделать краткое отступление и обсудить детали работы менеджера компоновки.
Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, I том, 2011