The grid geometry manager needs to know what to do if there's more space than necessary to display the widgets. It does this by allocating the extra space relative to the "weight" of each row and column. For example, if one column has a weight of 3 and another column has a weight of 1, the first column will be given 3 times the amount of extra space as the other column.

By default, rows and columns have a weight of zero. That means if there is extra space -- as in your example -- it goes unused.

The absolute simplest solution to your problem is to give each column an equal non-zero weight so that extra space is evenly distributed. You do that with the columnconfigure (or grid_columnconfigure) method:

root.grid_columnconfigure(0, weight=1)
root.grid_columnconfigure(1, weight=1)
root.grid_columnconfigure(2, weight=1)

Since you say you want the label to span all three columns, you need to tell grid that, which you can do by placing the label in column zero and giving it a columnspan of 3:

lbl.grid(row=1,column=0, columnspan=3)
Answer from Bryan Oakley on Stack Overflow
Top answer
1 of 2
1

The grid geometry manager needs to know what to do if there's more space than necessary to display the widgets. It does this by allocating the extra space relative to the "weight" of each row and column. For example, if one column has a weight of 3 and another column has a weight of 1, the first column will be given 3 times the amount of extra space as the other column.

By default, rows and columns have a weight of zero. That means if there is extra space -- as in your example -- it goes unused.

The absolute simplest solution to your problem is to give each column an equal non-zero weight so that extra space is evenly distributed. You do that with the columnconfigure (or grid_columnconfigure) method:

root.grid_columnconfigure(0, weight=1)
root.grid_columnconfigure(1, weight=1)
root.grid_columnconfigure(2, weight=1)

Since you say you want the label to span all three columns, you need to tell grid that, which you can do by placing the label in column zero and giving it a columnspan of 3:

lbl.grid(row=1,column=0, columnspan=3)
2 of 2
0

As default cells in grid have no size. You can only set minimal size using

root.columnconfigure(0, minsize=300)
root.columnconfigure(1, minsize=300)
root.columnconfigure(2, minsize=300)

To create big header you can connect 3 cells

lbl.grid(..., columnspan=3)

You can also use widget to cell size using sticky='we'

grid(..., sticky='we')

w = west/left, e = east/right

Working example:

import tkinter as tk

# --- functions ---

def fifties(selection):
    data = {
        "Intro": "1950's intro",
        "Political": "1950's politcal",
        "Economic": "1950's economic",
        "Social": "1950's social", 
        "Technological": "1950's technological",
        "Aesthetic": "1950's aesthetic",
    }

    if selection in data:
        text_1950['text'] = data[selection]
    else:
        text_1950['text'] = "Unknow selection: " + selection 

def sixties(selection):
    data = {
        "Intro": "1960's intro",
        "Political": "1960's politcal",
        "Economic": "1960's economic",
        "Social": "1960's social", 
        "Technological": "1960's technological",
        "Aesthetic": "1960's aesthetic",
    }

    if selection in data:
        text_1960['text'] = data[selection]
    else:
        text_1960['text'] = "Unknow selection: " + selection

def seventies(selection):
    data = {
        "Intro": "1970's intro",
        "Political": "1970's politcal",
        "Economic": "1970's economic",
        "Social": "1970's social", 
        "Technological": "1970's technological",
        "Aesthetic": "1970's aesthetic",
    }

    if selection in data:
        text_1970['text'] = data[selection]
    else:
        text_1970['text'] = "Unknow selection: " + selection

# --- main ---

# - init -
root = tk.Tk()
root.configure(bg="turquoise")
root.geometry("900x600")

# - set columns minimal size -

root.columnconfigure(0, minsize=300)
root.columnconfigure(1, minsize=300)
root.columnconfigure(2, minsize=300)

# - header -

lbl = tk.Label(root, text="Pick a Decade", bg="turquoise", fg="hot pink", font=("Times", 40, "bold italic"))
lbl.grid(column=0, row=0, columnspan=3, sticky='we')

# - menus -

options = ["Intro", "Political", "Economic", "Social", "Technological", "Aesthetic"]

var = tk.StringVar(value="1950's")
a = tk.OptionMenu(root, var, *options, command=fifties)
a.grid(column=0, row=2, sticky='we')

var = tk.StringVar(value="1960's")
a = tk.OptionMenu(root, var, *options, command=sixties)
a.grid(column=1, row=2, sticky='we')

var = tk.StringVar(value="1970's")
a = tk.OptionMenu(root, var, *options, command=seventies)
a.grid(column=2, row=2, sticky='we')

# - empty labels for text -

text_1950 = tk.Label(root, bg="turquoise")
text_1950.grid(column=0, row=3)

text_1960 = tk.Label(root, bg="turquoise")
text_1960.grid(column=1, row=3)

text_1970 = tk.Label(root, bg="turquoise")
text_1970.grid(column=2, row=3)

# - start -
root.mainloop()

🌐
ActiveState
activestate.com › home › resources › quick read › how to position widgets in tkinter
How to Position Widgets in Tkinter - with Grid, Place or Pack - ActiveState
January 24, 2024 - However, pack() is limited in precision compared to place() and grid() which feature absolute positioning. For simple positioning of widgets vertically or horizontally in relation to each other, pack() is the layout manager of choice. ... For more information about pack() and its options, refer to: How To Position Buttons in Tkinter With Pack · In this example, three labels (widgets that contain text or images) are positioned vertically in relation to each other, and are not padded.
🌐
Python.org
discuss.python.org › python help
Finding location of label in tkinter grid - Python Help - Discussions on Python.org
May 5, 2022 - Hi, I’m developing a project on Ludo game. I’d like to know how to find the current grid point of a coin(Label). So I can check like grid(coin)==grid(center) or not.
🌐
Python Tutorial
pythontutorial.net › home › tkinter tutorial › tkinter grid
Tkinter Grid Geometry Manager - Python Tutorial
April 4, 2025 - Use grid() method to position a widget on a grid. Use sticky option to align the position of the widget on a cell and define how the widget will be stretched. Use ipadx, ipady and padx, pady to add internal and external paddings.
🌐
Plus2Net
plus2net.com › python › tkinter-grid.php
Python Tkinter Grid Layout – Arrange Widgets Using Rows and Columns
February 5, 2019 - import tkinter as tk my_w = tk.Tk() ... ) label2.grid(row=1, column=1, sticky='nsew') my_w.mainloop() anchor helps position text or widgets within the grid cell, offering more fine-grained control over their layo...
🌐
Python Guides
pythonguides.com › python-tkinter-grid
How To Create Responsive Layouts With Python Tkinter's Grid Geometry Manager?
March 19, 2025 - Frames act as containers for other widgets and can be arranged using the Grid system just like any other widget. Let’s consider an example of a customer relationship management (CRM) application for a USA-based company: from tkinter import * root = Tk() # Customer Details Frame customer_frame = LabelFrame(root, text="Customer Details") customer_frame.grid(row=0, column=0, padx=10, pady=10, sticky="NSEW") name_label = Label(customer_frame, text="Name:") name_label.grid(row=0, column=0, sticky="E", padx=5, pady=5) name_entry = Entry(customer_frame) name_entry.grid(row=0, column=1, sticky="WE",
🌐
Python GUIs
pythonguis.com › tutorials › getting started with tkinter › using the grid geometry manager in tkinter
Using the Grid Geometry Manager in Tkinter
October 9, 2022 - To create the image, we use the tk.PhotoImage, which loads the image file named profile.png. Then, we position this label in the first row (row=0) and first column (column=0) of the grid.
🌐
Educative
educative.io › answers › how-to-display-items-in-a-tkinter-grid
How to display items in a Tkinter grid
We can place items based on the row and column index position in the grid. widget.grid(row="provide row index here", column = "provide column index here") Let us take a look at an example of this.
Find elsewhere
Top answer
1 of 4
25

There's no trick -- the widget is centered in the area allocated to it by default. Simply place a label in a cell without any sticky attributes and it will be centered.

Now, the other question is, how to get the area it is allocated to be centered. That depends on many other factors, such as what other widgets are there, how they are arranged, etc.

Here's a simple example showing a single centered label. It does this by making sure the row and column it is in takes up all extra space. Notice that the label stays centered no matter how big you make the window.

import Tkinter as tk

class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="This should be centered")
        label.grid(row=1, column=1)
        self.grid_rowconfigure(1, weight=1)
        self.grid_columnconfigure(1, weight=1)

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).grid(sticky="nsew")
    root.grid_rowconfigure(0, weight=1)
    root.grid_columnconfigure(0, weight=1)
    root.mainloop()

You can get a similar effect by giving a weight to all rows and columns except the one with the label.

import Tkinter as tk

class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="This should be centered")
        label.grid(row=1, column=1)

        self.grid_rowconfigure(0, weight=1)
        self.grid_rowconfigure(2, weight=1)
        self.grid_columnconfigure(0, weight=1)
        self.grid_columnconfigure(2, weight=1)

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).grid(sticky="nsew")
    root.grid_rowconfigure(0, weight=1)
    root.grid_columnconfigure(0, weight=1)

    root.mainloop()
2 of 4
8

There is nothing special required. A widget will be in the middle of it's parent automatically. What is required to to tell the parent to fill all available space.

from tkinter import *
root = Tk()
root.geometry("500x500+0+0")
frmMain = Frame(root,bg="blue")

startbutton = Button(frmMain, text="Start",height=1,width=4)
startbutton.grid()

#Configure the row/col of our frame and root window to be resizable and fill all available space
frmMain.grid(row=0, column=0, sticky="NESW")
frmMain.grid_rowconfigure(0, weight=1)
frmMain.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)

root.mainloop()

This uses grid rather than pack to place the widgets and the grid is configured to fill the entire size of the window. The button will appear in the centre regardless of the size of the window.

🌐
TkDocs
tkdocs.com › tutorial › grid.html
TkDocs Tutorial - The Grid Geometry Manager
If you want the widget to expand to fill up the entire cell, grid it with a sticky value of nsew (north, south, east, west), meaning it will stick to every side. This is shown in the bottom left widget in the above figure. Most widgets have options that can control how they are displayed if they are larger than needed. For example, a label widget has an anchor option that controls where the label's text will be positioned within the widget's boundaries.
🌐
GeeksforGeeks
geeksforgeeks.org › python-grid-method-in-tkinter
Python | grid() method in Tkinter - GeeksforGeeks
August 21, 2024 - You don’t have to specify the size of the grid beforehand; the manager automatically determines that from the widgets in it. ... # import tkinter module from tkinter import * from tkinter.ttk import * # creating main tkinter window/toplevel master = Tk() # this will create a label widget l1 = Label(master, text = "First:") l2 = Label(master, text = "Second:") # grid method to arrange labels in respective # rows and columns as specified l1.grid(row = 0, column = 0, sticky = W, pady = 2) l2.grid(row = 1, column = 0, sticky = W, pady = 2) # entry widgets, used to take entry from user e1 = Entry(master) e2 = Entry(master) # this will arrange entry widgets e1.grid(row = 0, column = 1, pady = 2) e2.grid(row = 1, column = 1, pady = 2) # infinite loop which can be terminated by keyboard # or mouse interrupt mainloop()
🌐
Tutorialspoint
tutorialspoint.com › python › tk_grid.htm
Tkinter grid() Method
from tkinter import * root = Tk( ) b=0 for r in range(6): for c in range(6): b=b+1 Button(root, text=str(b), borderwidth=1 ).grid(row=r,column=c) root.mainloop() This would produce the following result displaying 12 labels arrayed in a 3 x 4 grid − · python_gui_programming.htm ·
🌐
CopyProgramming
copyprogramming.com › howto › python-move-position-of-tkinter-label-code-example
Python: Example code for moving the position of a Tkinter label using Python
June 5, 2023 - To make the label expand across all three columns, inform grid by positioning the label in column zero and assigning it a columnspan value of 3.
🌐
Medium
medium.com › @fulton_shaun › tkinter-ui-layout-with-grid-and-place-b4bef98c0ad4
Tkinter: UI Layout with grid() and place() | by Shaun Fulton | Medium
May 25, 2025 - You’ll learn how to place widgets in rows and columns, apply padding, and use sticky alignment to position them precisely. The difference between .pack(), .grid(), and .place() ... Tkinter gives you three layout managers to control where your widgets go. Each one has its own style and purpose: ... For most real apps, use .grid() for structured UIs and .pack() for simpler stacks. .place() is niche! Let’s build a simple login form with two labels, two entries, and a button — all lined up in a clean two-column layout.
Top answer
1 of 2
16

I have had success using both justify and anchor:

Label(self, text=text, justify="left", anchor="w").grid(sticky = W, column=0,row=0)
2 of 2
8

I think your problem lies in the fact that each time you create a new instance of LabeledFrame, you are placing both the Entry & Label within the same Frame.

The grid settings for this Frame are separate from any other Frame, so it is impossible for LabeledFrames to align columns as they do not have the same values for column widths.

Normally to accomplish what you are after you would simply put sticky = W in the grid options for the Entry widget to left-justify the contents of the cell. However, this will only work for each individual Frame, leaving the contents of each separate LabeledFrame out of alignment.

Easiest way to fix this without changing much code:

You'll want to add a line to your for loop. If you specify a large minimum-width of the column that self.field's Frame is inserted into, you can be sure that things will align how you want them to. I've also added config options to the grid calls within the LabeledEntry class: sticky = W for the Label & sticky = E for the Entry.

Try this out and see if it solves your problem. If you would like the column to take less space simply reduce minsize.

from Tkinter import *

class LabeledEntry(Frame):
    def __init__(self, parent, *args, **kargs):
        text = kargs.pop("text")
        Frame.__init__(self, parent)
        Label(self, text=text, justify=LEFT).grid(sticky = W, column=0,row=0)
        Entry(self, *args, **kargs).grid(sticky = E, column=1, row=0)

class User_Input:
    def __init__(self, parent):
        fields = ['Text Label 1', 'This is the text Label 2']
        GUIFrame =Frame(parent)
        GUIFrame.pack(expand=True, anchor=NW)
        parent.minsize(width=350, height=325)
        field_index = 1
        for field in fields:
            self.field = LabeledEntry(GUIFrame, text=field)
            self.field.grid(column=0, row=field_index)
            self.field.grid_columnconfigure(index = 0, minsize = 150)
            field_index += 1
        self.Button2 = Button(parent, text='exit', command= parent.quit)
        self.Button2.place(x=25, y=300)

root = Tk()

MainFrame =User_Input(root)
root.mainloop()
Top answer
1 of 3
7

You should take a divide-and-conquer approach to laying out widgets in a GUI. Don't try to do everything at once or use one geometry manager to coordinate everything in one window. Be methodical, and tackle one small problem at a time.

For example, in your target GUI it appears you have four sections: the contact list, a search box and button, a new contact form, and something in the lower right corner (search results?). If I am correct that those are four distinct areas, start by creating four frames. Use grid to place them in the four corners of the main window. Give each frame a distinct color (for debugging purposes). Now, fiddle with options until those four areas grow and shrink in the way that you want. Make sure you give the columns and rows weight so that they all resize properly.

Now that you've done that, you have four smaller, more manageable layout problems. Now, it could be that I'm wrong -- maybe you have two areas, left and right. Or maybe you have three -the left, and then the upper right and the lower right. For now we'll assume I'm right but the technique remains the same regardless.

It looks like you already have the layout for the contact form, so move those into the upper-right frame. Make sure they all expand and shrink properly when you grown and shrink the window (and thus, you grow and shrink the containing frame).

Once you have done that, work on the next section -- put the contact list in the upper left corner. Again, make sure it all resizes properly. At this point you shouldn't have to worry about the widgets on the right because you already have those sorted out. For this section you don't need grid, you can use pack since it's just a couple widgets stacked on top of each other. However, you can use whichever makes the most sense.

Continue on this way, working on the remaining two corners of the GUI. Be methodical, and tackle small independent sections one at a time.

2 of 3
7

I did something similar, check it out:

from Tkinter import Tk, N, S, W, E, BOTH, Text, Frame,Label, Button,Checkbutton, IntVar,Entry


class Example(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent)   
        self.parent = parent
        self.initUI()

    def initUI(self):      
        self.parent.title("Windows")


        Label(text="Contact List").grid(row=0,column=0,columnspan=2)
        Text(width=30,height=15).grid(row=1,rowspan=9, column=0,columnspan=2,padx=20)
        Button(text="Display Contact").grid(row=10, column=0,columnspan=2,pady=10)
        Label(text="Last Name:").grid(row=11, column=0,pady=10)
        Entry().grid(row=11,column=1)
        Button(text="Search").grid(row=12,column=0,columnspan=2)



        Label(text="New Contact").grid(row=0,column=2,columnspan=2)
        Label(text="First Name:").grid(row=1,column=2,sticky=E)
        Entry().grid(row=1,column=3)
        Label(text="Last Name:").grid(row=2,column=2,sticky=E)
        Entry().grid(row=2,column=3)
        Label(text="Phone #:").grid(row=3,column=2,sticky=E)
        Entry().grid(row=3,column=3)
        friend_check = IntVar()
        Checkbutton(variable=friend_check, command = self.friend_box, text = "Friend").grid(row=4,column=3,sticky=W)
        #Label(text="Friend").grid(row=4,column=3,padx=20,sticky=W)
        Label(text="Email:").grid(row=5,column=2,sticky=E)
        Entry().grid(row=5,column=3)
        Label(text="Birthday:").grid(row=6,column=2,sticky=E)
        Entry().grid(row=6,column=3)
        Button(text="Add Contact").grid(row=7,column=3,sticky=E)

    def friend_box(self):
        if friend_check.get() == 1:
            print '1'
        else:
            print '0'


def main():

    root = Tk()
    root.geometry("600x450+900+300")
    root.resizable(0,0)
    app = Example(root)
    root.mainloop()  


if __name__ == '__main__':
    main()  
🌐
GeeksforGeeks
geeksforgeeks.org › setting-the-position-of-tkinter-labels
Setting the position of TKinter labels | GeeksforGeeks
April 28, 2025 - It is also used to perform tasks such as to underline the part of the text and span the text across multiple lines. ... We can use place() method to set the position of the Tkinter labels.
🌐
Python Tutorial
pythontutorial.net › home › tkinter tutorial › tkinter label
Tkinter Label - Python Tutorial
April 3, 2025 - If you don’t call the pack() function, the program still creates the label but does not show it on the main window. The pack() function is one of three geometry managers in Tkinter, including: Pack · Grid · Place · You’ll learn about this in detail in the upcoming tutorials.