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". Этого достаточно, чтобы панель оставалась внизу и растягивалась по горизонтали при изменении размеров окна.