2026, Jan 04 15:02
Как закрепить футер внизу окна Tkinter с grid и растянуть по ширине
Как заменить pack на grid в Tkinter и закрепить статусную панель внизу окна. Настраиваем rowconfigure/columnconfigure и sticky=ew: футер тянется по ширине.
Когда вы переводите статусную панель, похожую на нижний колонтитул, с pack() на grid() в Tkinter, она должна оставаться «прижатой» к нижнему краю и тянуться по горизонтали при изменении размера окна. Секрет не в самом виджете, а в том, как верхнеуровневое окно распределяет пространство.
Проблема
Нужно закрепить полосу внизу и позволить ей растягиваться по ширине — но сделать это через grid(). Ниже минимальный пример, который даёт нужное поведение с pack().
import tkinter as tk
from tkinter import ttk
accent = 'blue'
class FooterBar(ttk.Frame):
def __init__(self, host):
super().__init__(host)
self.columnconfigure(0, weight=1)
self.rowconfigure(0, weight=1)
self.info = tk.Label(self, text="STATUS BAR")
self.info.grid()
self.pack(fill='x', expand=True, anchor='s')
class MainWindow(tk.Tk):
def __init__(self):
super().__init__()
self.title('Replace')
self.geometry('800x500')
self.resizable(1, 1)
self.configure(bg=accent)
if __name__ == "__main__":
ui = MainWindow()
bar = FooterBar(ui)
ui.mainloop()
Что происходит на самом деле
При pack() нижняя панель якорится к южной стороне окна и заполняет его по горизонтали. Чтобы повторить это в grid(), нужно управлять тем, как верхний контейнер раздаёт свободное место. Свободное пространство следует отдать строке над футером, а сам футер поместить в следующую строку и указать ему растягиваться слева направо.
Решение
Вызовите rowconfigure() и columnconfigure() на верхнем окне, чтобы назначить вес строке 0 и столбцу 0; затем поместите футер в строку 1 и приклейте его по горизонтали (east–west). Уберите строку с pack() из класса футера и размещайте его через grid() на родителе.
import tkinter as tk
from tkinter import ttk
accent = 'blue'
class FooterBar(ttk.Frame):
def __init__(self, host):
super().__init__(host)
self.columnconfigure(0, weight=1)
self.rowconfigure(0, weight=1)
self.info = tk.Label(self, text="STATUS BAR")
self.info.grid()
class MainWindow(tk.Tk):
def __init__(self):
super().__init__()
self.title('Replace')
self.geometry('800x500')
self.resizable(1, 1)
self.configure(bg=accent)
if __name__ == "__main__":
ui = MainWindow()
# отдать доступное пространство строке 0 и столбцу 0
ui.rowconfigure(0, weight=1)
ui.columnconfigure(0, weight=1)
bar = FooterBar(ui)
# поместить футер внизу и заставить его заполнять по горизонтали
bar.grid(row=1, column=0, sticky="ew")
ui.mainloop()
Почему это важно
В grid() результат компоновки зависит от того, как контейнер распределяет свободное место. Назначив вес строке 0 и столбцу 0, вы обеспечиваете, что расширение будет происходить над футером: статусная панель остаётся визуально «прикреплённой» к нижнему краю и при этом растягивается по ширине окна. Без такого распределения футер не будет вести себя как версия на pack().
Итоги
Чтобы заменить pack() на grid() для футера: назначьте вес строке 0 и столбцу 0 у родителя, поместите футер в строку 1 и используйте sticky="ew". Этого достаточно, чтобы панель оставалась внизу и растягивалась по горизонтали при изменении размеров окна.