GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Python 3
  • Скачать Python
  • IDE
  • Скачать PyCharm
  • Django
  • Tkinter
  • Книги

This view

  • Original page
  • New address

GeezerVison is showing python-scripts.com — Разметки pack, grid и place для позиционирования в Tkinter

Разметка виджетов в Tkinter

В данном уроке по изучению Tkinter мы познакомимся с менеджерами разметки. Когда мы создаем графический интерфейс нашего приложения, мы определяем, какие виджеты будем использовать, и как они будут расположены в приложении. Для того, чтобы организовать виджеты в приложении, используются специальные невидимые объекты – менеджеры разметки.

Содержание курса

  1. Создание окна по центру и кнопка выхода в Tkinter
  2. Разметка виджетов в Tkinter — pack, grid и place
  3. Виджеты Checkbutton, Label, Scale и Listbox в Tkinter
  4. Меню, подменю и панель инструментов в Tkinter
  5. Диалоговые окна в Tkinter
  6. Рисуем линии, прямоугольники, круг и текст в Tkinter
  7. Пишем игру змейка на Tkinter

Содержание статьи

  • Метод place() в Tkinter — Абсолютное позиционирование
  • Tkinter pack() — размещение виджетов по горизонтали и вертикали
  • Пример создания кнопок в Tkinter
  • Создаем приложение для отзывов на Tkinter
  • Разметка grid() в Tkinter для создания калькулятора
  • Пример создания диалогового окна в Tkinter

Существует два вида виджетов:

  • контейнеры;
  • дочерние виджеты.

Контейнеры объединяют виджеты для формирования разметки. У Tkinter есть три встроенных менеджера разметки: pack, grid и place.

  • Place – это менеджер геометрии, который размещает виджеты, используя абсолютное позиционирование.
  • Pack – это менеджер геометрии, который размещает виджеты по горизонтали и вертикали.
  • Grid – это менеджер геометрии, который размещает виджеты в двухмерной сетке.

Метод place() в Tkinter — Абсолютное позиционирование

В большинстве случаев разработчикам необходимо использовать менеджеры разметки. Есть несколько ситуаций, в которых следует использовать именно абсолютное позиционирование. В рамках абсолютного позиционирования разработчик определяет позицию и размер каждого виджета в пикселях. Во время изменения размеров окна размер и позиция виджетов не меняются.

Изображения из примера:

  • bardejov.jpg
  • rotunda.jpg
  • mincol.jpg

Сохраните их в папке рядом с файлом absolute.py код для которого будет ниже.

Таким образом, на разных платформах приложения выглядят по-разному. То, что выглядит нормально на Linux, может отображаться некорректно на Mac OS. Изменение шрифтов в нашем приложении также может испортить разметку. Если мы переведем наше приложение на другой язык, мы должны доработать и разметку.

absolute.py
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
from PIL import Image, ImageTk
from tkinter import Tk, BOTH
from tkinter.ttk import Frame, Label, Style
 
class Example(Frame):
 
    def __init__(self):
        super().__init__()
 
        self.initUI()
 
 
    def initUI(self):
 
        self.master.title("Absolute positioning")
        self.pack(fill=BOTH, expand=1)
 
        Style().configure("TFrame", background="#333")
 
        bard = Image.open("bardejov.jpg")
        bardejov = ImageTk.PhotoImage(bard)
        label1 = Label(self, image=bardejov)
        label1.image = bardejov
        label1.place(x=20, y=20)
 
        rot = Image.open("rotunda.jpg")
        rotunda = ImageTk.PhotoImage(rot)
        label2 = Label(self, image=rotunda)
        label2.image = rotunda
        label2.place(x=40, y=160)
 
        minc = Image.open("mincol.jpg")
        mincol = ImageTk.PhotoImage(minc)
        label3 = Label(self, image=mincol)
        label3.image = mincol
        label3.place(x=170, y=50)
 
 
def main():
 
    root = Tk()
    root.geometry("300x280+300+300")
    app = Example()
    root.mainloop()
 
 
if __name__ == '__main__':
    main()

В этом примере мы расположили три изображения при помощи абсолютного позиционирования. Мы использовали менеджер геометрии place.

Python
1
from PIL import Image, ImageTk

Мы использовали Image и ImageTk из модуля PIL (Python Imaging Library).

Python
1
2
style = Style()
style.configure("TFrame", background="#333")

При помощи стилей, мы изменили фон нашего окна на темно-серый.

Python
1
2
bard = Image.open("bardejov.jpg")
bardejov = ImageTk.PhotoImage(bard)

Мы создали объект изображения и объект фото изображения из сохраненных ранее изображений в текущей рабочей директории.

Python
1
label1 = Label(self, image=bardejov)

Мы создали Label (ярлык) с изображением. Данные ярлыки могут содержать как изображения, так и текст.

Python
1
label1.image = bardejov

Нам нужно сохранить ссылку на изображение, чтобы не потерять его если сборщик мусора (Garbage collector) его не закроет.

Python
1
label1.place(x=20, y=20)

Ярлык размещен в рамке по координатам x=20 и y=20.

place() Абсолютное позиционирование

Tkinter pack() — размещение виджетов по горизонтали и вертикали

Менеджер геометрии pack() упорядочивает виджеты в горизонтальные и вертикальные блоки. Макетом можно управлять с помощью параметров fill, expand и side.

Пример создания кнопок в Tkinter

В следующем примере мы разместим две кнопки в нижнем правом углу нашего окна. Для этого мы воспользуемся менеджером pack.

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
from tkinter import Tk, RIGHT, BOTH, RAISED
from tkinter.ttk import Frame, Button, Style
 
 
class Example(Frame):
 
    def __init__(self):
        super().__init__()
        self.initUI()
 
    def initUI(self):
        self.master.title("Кнопки в kinter")
        self.style = Style()
        self.style.theme_use("default")
 
        frame = Frame(self, relief=RAISED, borderwidth=1)
        frame.pack(fill=BOTH, expand=True)
 
        self.pack(fill=BOTH, expand=True)
 
        closeButton = Button(self, text="Закрыть")
        closeButton.pack(side=RIGHT, padx=5, pady=5)
        okButton = Button(self, text="Готово")
        okButton.pack(side=RIGHT)
 
 
def main():
 
    root = Tk()
    root.geometry("300x200+300+300")
    app = Example()
    root.mainloop()
 
 
if __name__ == '__main__':
    main()

Есть вопросы по Python?

На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!

Python Форум Помощи

Telegram Чат & Канал

Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!

Чат
Канал

Паблик VK

Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!

Подписаться

У нас есть две рамки. Первая рамка – основная, а также вторая – дополнительная, которая растягивается в обе стороны и сдвигает две кнопки в нижнюю часть основной рамки. Кнопки находятся в горизонтальном контейнере и размещены в ее правой части.

Python
1
2
frame = Frame(self, relief=RAISED, borderwidth=1)
frame.pack(fill=BOTH, expand=True)

Мы создали еще один виджет Frame. Этот виджет занимает практически все пространство окна. Мы изменяем границы рамки, чтобы сама рамка была видна. По умолчанию она плоская.

Python
1
2
closeButton = Button(self, text="Закрыть")
closeButton.pack(side=RIGHT, padx=5, pady=5)

Кнопка closeButton создана. Она расположена в горизонтальном контейнере. Параметр side позволяет поместить кнопку в правой части горизонтальной полосы. Параметры padx и pady позволяют установить отступ между виджетами. Параметр padx устанавливает пространство между виджетами кнопки closeButton и правой границей корневого окна.

Python
1
okButton.pack(side=RIGHT)

Кнопка okButton размещена возле closeButton с установленным отступом (padding) в 5 пикселей.

pack() - размещение виджетов по горизонтали и вертикали

Создаем приложение для отзывов на Tkinter

Менеджер pack – это простой менеджер разметки. Его можно использовать для простых задач разметки. Чтобы создать более сложную разметку, необходимо использовать больше рамок, каждая из которых имеет собственный менеджер разметки.

review.py
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
from tkinter import Tk, Text, BOTH, X, N, LEFT
from tkinter.ttk import Frame, Label, Entry
 
 
class Example(Frame):
 
    def __init__(self):
        super().__init__()
        self.initUI()
 
    def initUI(self):
        self.master.title("Оставить отзыв")
        self.pack(fill=BOTH, expand=True)
 
        frame1 = Frame(self)
        frame1.pack(fill=X)
 
        lbl1 = Label(frame1, text="Заголовок", width=10)
        lbl1.pack(side=LEFT, padx=5, pady=5)
 
        entry1 = Entry(frame1)
        entry1.pack(fill=X, padx=5, expand=True)
 
        frame2 = Frame(self)
        frame2.pack(fill=X)
 
        lbl2 = Label(frame2, text="Автор", width=10)
        lbl2.pack(side=LEFT, padx=5, pady=5)
 
        entry2 = Entry(frame2)
        entry2.pack(fill=X, padx=5, expand=True)
 
        frame3 = Frame(self)
        frame3.pack(fill=BOTH, expand=True)
 
        lbl3 = Label(frame3, text="Отзыв", width=10)
        lbl3.pack(side=LEFT, anchor=N, padx=5, pady=5)
 
        txt = Text(frame3)
        txt.pack(fill=BOTH, pady=5, padx=5, expand=True)
 
 
def main():
 
    root = Tk()
    root.geometry("300x300+300+300")
    app = Example()
    root.mainloop()
 
 
if __name__ == '__main__':
    main()

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

Python
1
self.pack(fill=BOTH, expand=True)

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

Python
1
2
3
4
5
6
7
8
frame1 = Frame(self)
frame1.pack(fill=X)
 
lbl1 = Label(frame1, text="Заголовок", width=10)
lbl1.pack(side=LEFT, padx=5, pady=5)
 
entry1 = Entry(frame1)
entry1.pack(fill=X, padx=5, expand=True)

Первые два виджета размещены на первой рамке. Поле для ввода данных растянуто горизонтально с параметрами fill и expand.

Python
1
2
3
4
5
6
7
8
frame3 = Frame(self)
frame3.pack(fill=BOTH, expand=True)
 
lbl3 = Label(frame3, text="Отзыв", width=10)
lbl3.pack(side=LEFT, anchor=N, padx=5, pady=5)        
 
txt = Text(frame3)
txt.pack(fill=BOTH, pady=5, padx=5, expand=True)

В третьей рамке мы разместили ярлык и виджет для ввода текста. Ярлык закреплен по северной стороне anchor=N, а виджет текста занимает все остальное пространство.

приложение для отзывов на Tkinter

Разметка grid() в Tkinter для создания калькулятора

Менеджер геометрии grid() в Tkinter используется для создания сетки кнопок для калькулятора.

calculator.py
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
from tkinter import Tk, W, E
from tkinter.ttk import Frame, Button, Entry, Style
 
 
class Example(Frame):
 
    def __init__(self):
        super().__init__()
        self.initUI()
 
    def initUI(self):
        self.master.title("Калькулятор на Tkinter")
 
        Style().configure("TButton", padding=(0, 5, 0, 5), font='serif 10')
 
        self.columnconfigure(0, pad=3)
        self.columnconfigure(1, pad=3)
        self.columnconfigure(2, pad=3)
        self.columnconfigure(3, pad=3)
 
        self.rowconfigure(0, pad=3)
        self.rowconfigure(1, pad=3)
        self.rowconfigure(2, pad=3)
        self.rowconfigure(3, pad=3)
        self.rowconfigure(4, pad=3)
 
        entry = Entry(self)
        entry.grid(row=0, columnspan=4, sticky=W+E)
        cls = Button(self, text="Очистить")
        cls.grid(row=1, column=0)
        bck = Button(self, text="Удалить")
        bck.grid(row=1, column=1)
        lbl = Button(self)
        lbl.grid(row=1, column=2)
        clo = Button(self, text="Закрыть")
        clo.grid(row=1, column=3)
        sev = Button(self, text="7")
        sev.grid(row=2, column=0)
        eig = Button(self, text="8")
        eig.grid(row=2, column=1)
        nin = Button(self, text="9")
        nin.grid(row=2, column=2)
        div = Button(self, text="/")
        div.grid(row=2, column=3)
 
        fou = Button(self, text="4")
        fou.grid(row=3, column=0)
        fiv = Button(self, text="5")
        fiv.grid(row=3, column=1)
        six = Button(self, text="6")
        six.grid(row=3, column=2)
        mul = Button(self, text="*")
        mul.grid(row=3, column=3)
 
        one = Button(self, text="1")
        one.grid(row=4, column=0)
        two = Button(self, text="2")
        two.grid(row=4, column=1)
        thr = Button(self, text="3")
        thr.grid(row=4, column=2)
        mns = Button(self, text="-")
        mns.grid(row=4, column=3)
 
        zer = Button(self, text="0")
        zer.grid(row=5, column=0)
        dot = Button(self, text=".")
        dot.grid(row=5, column=1)
        equ = Button(self, text="=")
        equ.grid(row=5, column=2)
        pls = Button(self, text="+")
        pls.grid(row=5, column=3)
 
        self.pack()
 
 
def main():
    root = Tk()
    app = Example()
    root.mainloop()
 
 
if __name__ == '__main__':
    main()

Менеджер grid() используется для организации кнопок в контейнере рамки.

Python
1
2
Style().configure("TButton", padding=(0, 5, 0, 5),
    font='serif 10')

Мы настроили виджет кнопки так, чтобы отображался специфический шрифт и применялся отступ (padding) в 3 пикселя.

Python
1
2
3
self.columnconfigure(0, pad=3)
...        
self.rowconfigure(0, pad=3)

Мы использовали методы columnconfigure() и rowconfigure() чтобы создать определенное пространство в сетке строк и столбцов. Благодаря этому шагу мы разделяем кнопки определенным пустым пространством.

Python
1
2
entry = Entry(self)
entry.grid(row=0, columnspan=4, sticky=W+E)

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

Параметр sticky расширяет виджет в указанном направлении. В нашем случае, мы можем убедиться, что наш виджет графы ввода был расширен слева направо W+E (восток-запад).

Python
1
2
cls = Button(self, text="Очистить")
cls.grid(row=1, column=0)

Кнопка очистки установлена во второй строке и первом столбце. Стоит отметить, что строки и столбцы начинаются с нуля.

Python
1
self.pack()

Метод pack() показывает виджет рамки и дает ей первоначальный размер. Если дополнительные параметры не указываются, размер будет таким, чтобы все дочерние виджеты могли поместиться. Этот метод компонует виджет рамки в верхнем корневом окне, которое также является контейнером. Менеджер grid() используется для организации кнопок в виджете рамки.

Создание калькулятора на Tkinter

Пример создания диалогового окна в Tkinter

Следующий пример создает диалоговое окно, используя менеджер геометрии grid.

windows.py
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
from tkinter import Tk, Text, BOTH, W, N, E, S
from tkinter.ttk import Frame, Button, Label, Style
 
 
class Example(Frame):
 
    def __init__(self):
        super().__init__()
        self.initUI()
 
 
    def initUI(self):
 
        self.master.title("Диалоговое окно в Tkinter")
        self.pack(fill=BOTH, expand=True)
 
        self.columnconfigure(1, weight=1)
        self.columnconfigure(3, pad=7)
        self.rowconfigure(3, weight=1)
        self.rowconfigure(5, pad=7)
 
        lbl = Label(self, text="Окна")
        lbl.grid(sticky=W, pady=4, padx=5)
 
        area = Text(self)
        area.grid(row=1, column=0, columnspan=2, rowspan=4, padx=5, sticky=E+W+S+N)
 
        abtn = Button(self, text="Активир.")
        abtn.grid(row=1, column=3)
 
        cbtn = Button(self, text="Закрыть")
        cbtn.grid(row=2, column=3, pady=4)
 
        hbtn = Button(self, text="Помощь")
        hbtn.grid(row=5, column=0, padx=5)
 
        obtn = Button(self, text="Готово")
        obtn.grid(row=5, column=3)
 
 
def main():
 
    root = Tk()
    root.geometry("350x300+300+300")
    app = Example()
    root.mainloop()
 
 
if __name__ == '__main__':
    main()

В этом примере мы использовали виджет ярлыка, текстовой виджет и четыре кнопки.

Python
1
2
3
4
self.columnconfigure(1, weight=1)
self.columnconfigure(3, pad=7)
self.rowconfigure(3, weight=1)
self.rowconfigure(5, pad=7)

Мы добавили небольшое пространство между виджетами в сетке. Параметр weight создает возможность расширения второго столбца и четвертого ряда. В этом ряду и столбце находится текстовой виджет, поэтому оставшееся пространство заполняет данный виджет.

Python
1
2
lbl = Label(self, text="Окна")
lbl.grid(sticky=W, pady=4, padx=5)

Виджет ярлыка также создается и помещается в сетку. Если не указываются ряд и столбец, тогда он займет первый ряд и столбец. Ярлык закрепляется у западной части окна sticky=W и имеет определенные отступы вокруг своих границ.

Python
1
2
3
area = Text(self)
area.grid(row=1, column=0, columnspan=2, rowspan=4,
    padx=5, sticky=E+W+S+N)

Создается текстовый виджет и помещается во второй ряд и первый столбец. Он охватывает два столбца и четыре строки.

Между виджетом и левым краем корневого окна присутствует пространство в 4 пикселя. Также, виджет закреплен около всех четырех сторон. Поэтому, когда окно расширяется, виджеты текстов увеличиваются во всех направлениях.

Python
1
2
3
4
5
abtn = Button(self, text="Активир.")
abtn.grid(row=1, column=3)
 
cbtn = Button(self, text="Закрыть")
cbtn.grid(row=2, column=3, pady=4)

Эти две кнопки находятся возле текстового виджета.

Python
1
2
3
4
5
hbtn = Button(self, text="Помощь")
hbtn.grid(row=5, column=0, padx=5)
 
obtn = Button(self, text="Готово")
obtn.grid(row=5, column=3)

Эти две кнопки находятся под текстовым виджетом. Кнопка «Помощь» расположена в первом столбце, а кнопка «Готово» в последнем столбце.
В этой части изучения Tkinter мы рассказали о работе с разметкой виджетов.

Создание диалогового окна в Tkinter

Vasile Buldumac

Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.

E-mail: [email protected]

Образование
Universitatea Tehnică a Moldovei (utm.md)

  • 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
  • 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.