Python Tkinter Frame
The Python Tkinter Frame outlines the frame or “structure” for your Tkinter window of a fixed size. Just like the human skeleton, a Tkinter window requires a frame to support it and give it a proper shape.
The Tkinter frame is useful for organizing your widgets in a specified area within the window. You also have the option to create Frames within Frames, allowing for better organization of widgets.
Frame Syntax:
frame1 = tk.Frame(master, option1, option2, . )
The first parameter of the Frame Widget always has to point to a Tkinter instance and is the only compulsory parameter. All others are optional.
List of Options
Tkinter Frame Example:
Every widget in Tkinter requires a “parent” or “master” which they take as the first parameter. Normally, the object created from Tk() called root is used as the parent. However when using frames, the widgets meant to be in the frame will take the frame as their parent.
Basically while the Tkinter frame will take root as the parent, the widgets will take one of the many frames we created as their parent.
from tkinter import * root = Tk() root.geometry("200x150") frame = Frame(root) frame.pack() leftframe = Frame(root) leftframe.pack(side=LEFT) rightframe = Frame(root) rightframe.pack(side=RIGHT) label = Label(frame, text = "Hello world") label.pack() button1 = Button(leftframe, text = "Button1") button1.pack(padx = 3, pady = 3) button2 = Button(rightframe, text = "Button2") button2.pack(padx = 3, pady = 3) button3 = Button(leftframe, text = "Button3") button3.pack(padx = 3, pady = 3) root.title("Test") root.mainloop()
In the code above we’ve created several Tkinter frames and packed them side by side. Next we’ve created a few other widgets like a Buttons and a Label which we insert into the frames we made. Check the image below to see the output of the above code.
The above code will make more sense once you go through the tutorials for other widgets (buttons) and layouts (pack). Also remember that a Tkinter frame is also a widget. which is why you can add a frame within a frame. Instead of passing root as the frame’s parent, simply write the name of another frame. You can use this technique to create nested frames and diversify the layout options on your GUI program.
Code Explanation
- Using pack() instead of other placement functions like place() allows the frames and their contents to auto adjust as window size is adjusted. pack() can also take several parameters to adjust position of the widget.
- root.geometry(«width x height») is another way of setting the size for the whole window.
- root.title() is used to add a title on the title bar of the window.
- root.mainloop() triggers the GUI. Any modifications and widgets to be included should be written before it. More information on it can be found in this article.
Output:
We chose not to define any width or height for our Tkinter frames, thus their default size is that of the widgets contained within them.
Customizing the Tkinter Frame:
By updating the following lines in our code, we can add some extra color to our Tkinter frame, and by extension, our Tkinter window.
frame = Frame(root, bd = 5, bg = "purple") frame.pack() leftframe = Frame(root, bg = "blue", bd = 3) leftframe.pack(side=LEFT) rightframe = Frame(root, bg = "red", bd = 3) rightframe.pack(side=RIGHT)
You can see the boundaries of the Frames much clearer in here, now that they are colored.
You can make use of many other options shown in the table at the start of the article to further customize your frame.
Tkinter LabelFrame
Tkinter offers a variant of the Frame widget, called LabelFrame. This offers the same functionality as a regular frame, with a few additional features. Below is a simple implementation of the LabelFrame widget.
If you want to learn how to make this, follow this link to the Tkinter LabelFrame tutorial.
This marks the end of the Python Tkinter Frame Article. You can head back to the main Tkinter article using this link.. Any suggestions or contributions for our site, CodersLegacy are more than welcome. Questions regarding the tutorial can be asked in the comments section below.
# Frame() — рамка
Для сложных интерфейсов используют отдельные области позиционирования элементов.
Фрейм — вспомогательный виджет, создание которого происходит при помощи класса Frame() .
Фреймы размещают на главном окне, а уже в фреймах – виджеты:
from tkinter import * root = Tk() frame_top = Frame(root) # root можно не указывать frame_top.pack() label_1 = Label(frame_top, width=7, height=4, bg='yellow', text="1") label_1.pack(side=LEFT) label_2 = Label(frame_top, width=7, height=4, bg='orange', text="2") label_2.pack(side=LEFT) frame_bottom = Frame(root) frame_bottom.pack() label_3 = Label(frame_bottom, width=7, height=4, bg='lightgreen', text="3") label_3.pack(side=LEFT) label_4 = Label(frame_bottom, width=7, height=4, bg='lightblue', text="4") label_4.pack(side=LEFT) root.mainloop()
Кроме Frame существует похожий класс LabelFrame – фрейм с подписью. В отличие от простого фрейма у него есть свойство text:
from tkinter import * root = Tk() frame_top = LabelFrame(text="Верх") frame_top.pack() label_1 = Label(frame_top, width=7, height=4, bg='yellow', text="1") label_1.pack(side=LEFT) label_2 = Label(frame_top, width=7, height=4, bg='orange', text="2") label_2.pack(side=LEFT) frame_bottom = LabelFrame(text="Низ") frame_bottom.pack() label_3 = Label(frame_bottom, width=7, height=4, bg='lightgreen', text="3") label_3.pack(side=LEFT) label_4 = Label(frame_bottom, width=7, height=4, bg='lightblue', text="4") label_4.pack(side=LEFT) root.mainloop()
# Упражнения
- Допишите существующий код, добавив ниже фрэйм «Footer», в котором будут горизонтально находиться две метки с надписями «5», «6».
- Допишите существующий код, добавив на верх фрэйм «Header», в котором будут горизонтально находиться три кнопки с надписями «File», «View», «About». Реализуйте растяжение кнопок по ширине окна.
- Напишите программу с четырьмя кнопками, которые будут расположены в углах окна, и при изменении размера окна.
# Горизонтальное расположение
Как и для обычных виджетов, задавая параметры .pack() можно изменять положения фреймов. внеся изменения в наш код, мы получим левостороннее расположение фреймов:
frame_top.pack(side=LEFT) frame_bottom.pack(side=LEFT)
Кроме side у pack() есть другие параметры-свойства. Можно задавать внутренние ( ipadx и ipady ) и внешние ( padx и pady ) отступы:
frame_top.pack(padx=100, pady=50) frame_bottom.pack(ipadx=10, ipady=10)
В результате верхний фрейм отступает от всех ближайших элементов на заданное расстояние, область отступа обведена красной рамкой. В нижнем фрейме появились отступы элементов от рамки:
Когда устанавливаются внутренние отступы, то из-за того, что side прибивает виджет к левой границе, справа получаем отступ в 20 пикселей, а слева – ничего. Можно частично решить проблему, заменив внутренние отступы рамки на внешние отступы у меток. Изменим код следующим образом:
frame_bottom.pack() label_3.pack(side=LEFT, padx=10, pady=10) label_4.pack(side=LEFT, padx=10, pady=10)
Но тут появляется промежуток между метками. Чтобы его убрать, пришлось бы каждый виджет укладывать в свой собственный фрейм. Отсюда делаем вывод, что упаковщик tkinter удобен только для относительно простых интерфейсов.
# Упражнения
from tkinter import * import time def tick(): # get the current local time from the PC time2 = time.strftime('%H:%M:%S') # if time string has changed, update it clock.config(text=time2) # calls itself every 200 milliseconds to update the time # display as needed could use >200 ms clock.after(200, tick) root = Tk() clock = Label(root, font=('times', 20, 'bold'), bg='green') clock.pack(fill=BOTH, expand=1) tick() root.mainloop()
- Напишите программу с часами состоящую из трех рамок:
- рамка «Moscow time» выводит текущее время в виде: «Moscow time: 17:27:37»,
- рамка «Current time» выводит текущее время в виде: «Hour: 17 Minutes: 27 Second: 37»
- рамка «Left time until the new day» выводит сколько часов минут и секунд осталось до нового дня.
- одно-строчного текстового поля,
- метки с отображением знака «+»,
- второго одно-строчного текстового поля,
- кнопкой «=», при нажатии на которую результат вычисления выводиться в третье текстовое поле,
- третьего одно-строчного тестового поля.
- реализуйте растяжение виджетов по ширине в зависимости от ширины окна.
- Добавьте проверку деления на 0. С выводом сообщения об ошибке, в удобное для пользователя место. Консольный вывод сообщения об ошибке исключить.