2025, Dec 14 07:00
How to replace pack() with grid() in Tkinter to keep a footer status bar pinned to the bottom and filling width
Switch a Tkinter status bar from pack() to grid(): keep it docked to the bottom, stretch horizontally on resize, using rowconfigure and columnconfigure.
When you switch a footer-like status bar from pack() to grid() in Tkinter, it should stay pinned to the bottom and stretch horizontally as the window resizes. The trick is not in the widget itself, but in how the top-level window allocates space.
Problem
The goal is to keep the bar at the bottom and let it expand across the width, but do it with grid(). Below is a minimal setup that achieves the behavior with 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()
What’s actually happening
With pack(), the footer is anchored to the south side of the window and fills horizontally. To mirror that with grid(), you need to control how the top-level window distributes extra space. The available space should be given to a row above the footer, while the footer itself is placed in the next row and told to stretch left and right.
Solution
Use rowconfigure() and columnconfigure() on the top-level window to allocate space to row 0 and column 0, then put the footer into row 1 and make it stick east–west. Remove the pack() line from the footer class and grid() it on the parent instead.
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()
# allocate available space to row 0 and column 0
ui.rowconfigure(0, weight=1)
ui.columnconfigure(0, weight=1)
bar = FooterBar(ui)
# put the footer at the bottom and make it fill horizontally
bar.grid(row=1, column=0, sticky="ew")
ui.mainloop()
Why this matters
In grid(), the layout result depends on how the container distributes free space. Assigning weight to row 0 and column 0 ensures that expansion happens above the footer, keeping the status bar visually docked to the bottom while letting it stretch across the window width. Without that allocation, the footer wouldn’t behave like the original pack()-based version.
Takeaways
To replace pack() with grid() for a footer: assign weight to the parent’s row 0 and column 0, place the footer in row 1, and use sticky="ew". That’s enough to keep the bar at the bottom and make it expand horizontally as the window is resized.