Менеджер геометрии Tkinter Pack в Python

Tkinter использует менеджер геометрии для организации виджетов в окне. Tkinter поддерживает три менеджера геометрии:

  • pack
  • grid
  • place
Содержание

Tkinter pack geometry manager

Менеджер геометрии pack организует виджеты в блоки перед их размещением в виджете-контейнере, который может быть главным окном или фреймом.

Менеджер геометрии пакета имеет множество опций для упорядочивания виджетов:

  • Side
  • Expand
  • Fill
  • ipadx, ipady
  • padx, pady
  • Anchor

Прежде чем углубляться в каждую опцию, вам необходимо понять координаты x и y окна:

Координаты x и y окна

Верхний левый угол окна — это начало координат с координатой(0,0). Координата x увеличивается слева направо, а координата y увеличивается сверху вниз.

Параметры Tkinter pack

Создадим простую программу, иллюстрирующую работу менеджера геометрии pack:

import tkinter as tk

root = tk.Tk()
root.title('Tkinter Pack Layout')
root.geometry('600x400')

label1 = tk.Label(master=root, text='Tkinter',bg='red',fg='white')
label2 = tk.Label(master=root,text='Pack Layout',bg='green', fg='white')
label3 = tk.Label(master=root, text='Demo',bg='blue', fg='white')

label1.pack()
label2.pack()
label3.pack()

root.mainloop()

Программа имеет главное окно с тремя метками с красным, зеленым и синим фоном.

Чтобы использовать менеджер геометрии pack, вы вызываете pack() виджета. По умолчанию Tkinter pack размещает виджеты в одном направлении вертикально сверху вниз.

Вертикальное размещение объектов по умолчанию

Side

Параметр side определяет направление виджетов в макете пакета.

Параметр side имеет четыре варианта:

  • «top»: расположить виджеты сверху вниз по вертикали.
  • «bottom»: расположить виджеты снизу вверх по вертикали.
  • «left»: виджеты слева направо по горизонтали.
  • «right»: справа налево по горизонтали.

По умолчанию установлено значение «top», что позволяет расположить виджет вертикально сверху вниз.

Помимо строковых констант вы можете использовать предопределенные константы, предоставляемые модулем Tkinter:

  • tk.TOP
  • tk.BOTTOM
  • tk.LEFT
  • tk.RIGHT

Обратите внимание, что мы импортировали модуль Tkinter как tk.

Следующая программа явно устанавливает «top», что позволяет расположить метки вертикально сверху вниз:

import tkinter as tk

root = tk.Tk()
root.title('Tkinter Pack Layout')
root.geometry('600x400')

label1 = tk.Label(master=root, text='Tkinter',bg='red',fg='white')
label2 = tk.Label(master=root,text='Pack Layout',bg='green', fg='white')
label3 = tk.Label(master=root, text='Demo',bg='blue', fg='white')

label1.pack(side=tk.TOP)
label2.pack(side=tk.TOP)
label3.pack(side=tk.TOP)

root.mainloop()

При изменении side на tk.BOTTOM менеджер pack располагает метки снизу вверх по вертикали:

import tkinter as tk

root = tk.Tk()
root.title('Tkinter Pack Layout')
root.geometry('600x400')

label1 = tk.Label(master=root, text='Tkinter',bg='red',fg='white')
label2 = tk.Label(master=root,text='Pack Layout',bg='green', fg='white')
label3 = tk.Label(master=root, text='Demo',bg='blue', fg='white')

label1.pack(side=tk.BOTTOM)
label2.pack(side=tk.BOTTOM)
label3.pack(side=tk.BOTTOM)

root.mainloop()

Выход:

Пример изменения side на tk.BOTTOM

tk.LEFT располагает метки слева направо:

Пример расположения меток с tk.LEFT

tk.RIGHT располагает метки справа налево:

Пример расположения меток с tk.RIGHT

Пробелы для виджетов

В Tkinter есть два вида пробелов:

  • Пробел, который может занимать виджет.
  • Пробел, который будет занимать виджет.

По умолчанию виджет будет занимать только необходимое пространство для отображения своего содержимого. Однако виджет может занимать больше места.

Например, виджет Label будет иметь размер, равный размеру текста. Цвет фона показывает, что каждая метка имеет разную ширину, поскольку длина ее текста разная.

Expand

Параметр expand определяет, должен ли виджет расширяться, чтобы занять дополнительное пространство, выделенное контейнеру.

Если expand установлен на True, виджет будет расширяться, а если установлен на False, то нет. Параметр expand по умолчанию имеет значение False.

Параметр expand сильно зависит от параметра side. В следующей таблице показаны зависимости между параметрами side и expand, когда речь идет о пространстве виджета.

Side Expand
Top (или Bottom) Виджет может быть такой же ширины, как и контейнер, expand определит высоту виджета.
Left (или Right) Виджет может быть такой же высоты, как и контейнер, expand будет определять ширину виджета.

Следующая программа размещает виджеты Label вертикально сверху вниз и устанавливает параметр expand первого виджета Label в значение True, а двух других виджетов Label в значение False:

import tkinter as tk

root = tk.Tk()
root.title('Tkinter Pack Layout')
root.geometry('600x400')

label1 = tk.Label(master=root, text='Tkinter',bg='red',fg='white')
label2 = tk.Label(master=root,text='Pack Layout',bg='green', fg='white')
label3 = tk.Label(master=root, text='Demo',bg='blue', fg='white')

label1.pack(side=tk.TOP, expand=True)
label2.pack(side=tk.TOP, expand=False)
label3.pack(side=tk.TOP, expand=False)

root.mainloop()

Поскольку мы установили параметр expand первой метки в значение true, она занимает все вертикальное пространство и сдвигает два других виджета метки вниз:

Пример установки параметра expand первой метки в значение true

Следующая программа размещает виджеты Label горизонтально слева направо и устанавливает параметр expand первого виджета Label в значение True, а двух других виджетов Label в значение False:

import tkinter as tk

root = tk.Tk()
root.title('Tkinter Pack Layout')
root.geometry('600x400')

label1 = tk.Label(master=root, text='Tkinter',bg='red',fg='white')
label2 = tk.Label(master=root,text='Pack Layout',bg='green', fg='white')
label3 = tk.Label(master=root, text='Demo',bg='blue', fg='white')

label1.pack(side=tk.LEFT, expand=True)
label2.pack(side=tk.LEFT, expand=False)
label3.pack(side=tk.LEFT, expand=False)

root.mainloop()

Поскольку мы установили параметр expand первой метки в значение true, она занимает все горизонтальное пространство и сдвигает два других виджета метки вправо:

Размещение виджетов Label горизонтально слева направо

Если установить параметр expand трех виджетов Label на True, они будут занимать ровное горизонтальное пространство:

import tkinter as tk

root = tk.Tk()
root.title('Tkinter Pack Layout')
root.geometry('600x400')

label1 = tk.Label(master=root, text='Tkinter',bg='red',fg='white')
label2 = tk.Label(master=root,text='Pack Layout',bg='green', fg='white')
label3 = tk.Label(master=root, text='Demo',bg='blue', fg='white')

label1.pack(side=tk.LEFT, expand=True)
label2.pack(side=tk.LEFT, expand=True)
label3.pack(side=tk.LEFT, expand=True)

root.mainloop()

Выход:

Пример установки параметра expand трех виджетов Label на True

Fill

Параметр fill определяет, будет ли виджет занимать доступное пространство. Он принимает следующие значения: ‘x’, ‘y’, ‘both’ и ‘none’. По умолчанию — ‘none’.

Fill

Эффект
‘none’ Виджет не будет расширяться, чтобы заполнить дополнительное пространство. Он занимает только место, которое соответствует контенту.
‘х’ Виджет расширится по горизонтали, чтобы заполнить все дополнительное пространство по оси X.
‘y’ Виджет расширится по вертикали, чтобы заполнить все свободное пространство по оси Y.
‘both’ Будет расширяться как по горизонтали, так и по вертикали, заполняя все свободное пространство в обоих направлениях.

Следующая программа иллюстрирует, как работает параметр fill:

import tkinter as tk

root = tk.Tk()
root.title('Tkinter Pack Layout')
root.geometry('600x400')

label1 = tk.Label(master=root, text='Tkinter',bg='red',fg='white')
label2 = tk.Label(master=root,text='Pack Layout',bg='green', fg='white')
label3 = tk.Label(master=root, text='Fill',bg='blue', fg='white')
label4 = tk.Label(master=root, text='Demo',bg='purple', fg='white')

label1.pack(side=tk.TOP, expand=True, fill=tk.X)
label2.pack(side=tk.TOP, expand=True, fill=tk.Y)
label3.pack(side=tk.TOP, expand=True, fill=tk.NONE)
label4.pack(side=tk.TOP, expand=True, fill=tk.BOTH)


root.mainloop()

Выход:

Демонстрация работы параметра fill

В этом примере мы размещаем виджеты Label вертикально сверху вниз. Расширения всех виджетов Label установлены на True.

  • Первый виджет Label имеет значение заполнения tk.X, что позволяет ему заполнять дополнительные пространства вдоль оси x.
  • Второй виджет Label имеет значение заполнения tk.Y, что позволяет ему заполнять дополнительные пространства вдоль оси Y.
  • Третий виджет Label имеет значение заполнения tk.NONE, что означает, что он не расширяется для заполнения дополнительного пространства.
  • Четвертый виджет Label имеет значение заполнения tk.BOTH, что позволяет ему занимать любое дополнительное пространство как в горизонтальном, так и в вертикальном направлении.

Внутренние отступы: ipadx и ipady

Параметры ipadx и ipady создают внутренние отступы для виджетов:

  • ipadx создает отступы слева и справа или отступы вдоль оси x.
  • ipady создает отступы сверху и снизу или отступы вдоль оси Y.

Например, следующая программа использует параметры ipadx и ipady для установки внутренних отступов каждого виджета Label:

import tkinter as tk

root = tk.Tk()
root.title('Tkinter Pack Layout')
root.geometry('600x400')

label1 = tk.Label(master=root, text='Pack',bg='red',fg='white')
label2 = tk.Label(master=root,text='Pack',bg='green', fg='white')
label3 = tk.Label(master=root, text='Pack',bg='blue', fg='white')
label4 = tk.Label(master=root, text='Pack',bg='purple', fg='white')

label1.pack(side=tk.LEFT)
label2.pack(side=tk.LEFT, ipadx=40)
label3.pack(side=tk.LEFT, ipady=40)
label4.pack(side=tk.LEFT, ipadx=80, ipady=80)

root.mainloop()

Выход:

Пример внутренних отступов ipadx ipady

Внешние отступы: padx и pady

Параметры padx и pady позволяют указать отступы, которые будут добавлены по горизонтали и вертикали соответственно:

  • padx – представляет собой горизонтальный отступ, который добавляет пространство слева и справа от виджета.
  • pady – представляет собой вертикальный отступ, который добавляет пространство над или под виджетом.

Следующий пример иллюстрирует, как использовать pady:

import tkinter as tk

root = tk.Tk()
root.title('Tkinter Pack Layout')
root.geometry('600x400')

label1 = tk.Label(master=root, text='Pack',bg='red',fg='white')
label2 = tk.Label(master=root,text='Pack',bg='green', fg='white')
label3 = tk.Label(master=root, text='Pack',bg='blue', fg='white')
label4 = tk.Label(master=root, text='Pack',bg='purple', fg='white')

label1.pack(side=tk.TOP, fill=tk.X, pady=10)
label2.pack(side=tk.TOP, fill=tk.X, pady=20)
label3.pack(side=tk.TOP, fill=tk.X ,pady=40)
label4.pack(side=tk.TOP, fill=tk.X, pady=60)

root.mainloop()

Выход:

Пример использования pady

Следующая программа иллюстрирует, как использовать padx:

import tkinter as tk

root = tk.Tk()
root.title('Tkinter Pack Layout')
root.geometry('600x400')

label1 = tk.Label(master=root, text='Pack',bg='red',fg='white')
label2 = tk.Label(master=root,text='Pack',bg='green', fg='white')
label3 = tk.Label(master=root, text='Pack',bg='blue', fg='white')
label4 = tk.Label(master=root, text='Pack',bg='purple', fg='white')

label1.pack(side=tk.LEFT, fill=tk.X, padx=10)
label2.pack(side=tk.LEFT, fill=tk.X, padx=20)
label3.pack(side=tk.LEFT, fill=tk.X ,padx=40)
label4.pack(side=tk.LEFT, fill=tk.X, padx=60)

root.mainloop()

Выход:

Пример использования padx

Anchor

Параметр anchor позволяет прикрепить виджет к краю выделенного пространства. Он принимает одно из следующих значений:

Стик Описание
‘n’ Север или центр
‘s’ Юг или нижний центр
‘e’ Восток или правый центр
‘w’ Запад или левый центр
‘nw’ Северо-запад или верхний левый угол
‘ne’ Северо-восток или верхний правый угол
‘se’ Юго-Восток или нижний правый угол
‘sw’ Юго-запад или нижний левый угол
‘center’ Центр

На следующем рисунке показаны варианты anchor:

tkinter pack anchor - пример

Например, следующая программа показывает виджеты, использующие anchor E и W:

import tkinter as tk

root = tk.Tk()
root.title('Pack Demo')
root.geometry("350x200")

# box 1
box1 = tk.Label(root, text="Box 1", bg="green", fg="white")
box1.pack(ipadx=20, ipady=20, anchor=tk.E,  expand=True)

# box 2
box2 = tk.Label(root, text="Box 2", bg="red", fg="white")
box2.pack(ipadx=20, ipady=20, anchor=tk.W, expand=True)


root.mainloop()

Выход:

Пример виджетов, использующих anchor E и W

Использование пакета Tkinter для создания формы входа

В следующем примере метод pack() используется для создания формы входа:

import tkinter as tk
from tkinter import ttk

root = tk.Tk()
root.title('Login')
root.geometry("350x220")


fields = {}

fields['username_label'] = ttk.Label(text='Username:')
fields['username'] = ttk.Entry()

fields['password_label'] = ttk.Label(text='Password:')
fields['password'] = ttk.Entry(show="*")


for field in fields.values():
    field.pack(anchor=tk.W, padx=10, pady=5, fill=tk.X)

ttk.Button(text='Login').pack(anchor=tk.W, padx=10, pady=5)

root.mainloop()

Выход:

Создание формы входа с Tkinter pack

Как это работает.

  • Сначала инициализируем словарь для хранения виджетов:
fields = {}
  • Во-вторых, создайте виджеты «Label» и «Entry»:
fields['username_label'] = ttk.Label(text='Username:')
fields['username'] = ttk.Entry()

fields['password_label'] = ttk.Label(text='Password:')
fields['password'] = ttk.Entry(show="*")
  • В-третьих, пройдитесь по виджетам и упакуйте их:
for field in fields.values():
    field.pack(anchor=tk.W, padx=10, pady=5, fill=tk.X)
  • Наконец, добавьте кнопку входа:
ttk.Button(text='Login').pack(anchor=tk.W, padx=10, pady=5)
Похожие посты
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *