To center horizontally this should be enough

button.pack(side=TOP)

But to center horizontally and vertically you could use nested frames. Check the following script:

import tkinter as tk

#%% Frames
frameA = tk.Frame(background="#c8c8c8")
frameB = tk.Frame(width=200, height = 200, background="#646464")
# Nested Frame. framebb is created within frameB without width or height
framebb = tk.Frame(frameB, background="#646464")
frameC = tk.Frame(width=100, height = 100, background="bisque")

frameA.pack(side='top', fill=None)
frameB.pack(side='top')
# expand is the key parameter to center the framebb within frameB
framebb.pack(expand=True)
frameC.pack(side='bottom')

#frameA.pack_propagate(False)
frameB.pack_propagate(False)
frameC.pack_propagate(False)

#%% Buttons and Labels
tk.Label(frameA, text = "Text within the frame A").pack()

a = tk.Button(framebb, text = "A").pack()
b = tk.Button(framebb, text = "B").pack()
c = tk.Button(framebb, text = "C").pack()
d = tk.Button(frameC, text = "D").pack()
e = tk.Button(frameC, text = "E").pack()

tk.mainloop()

Another approach could be using the .grid() method

button.grid(row=1,col=0)

the values of row=1,col=0 depend of the position of the other widget in your window

or you can use .place(relx=0.5, rely=0.5, anchor=CENTER)

button.place(relx=0.5, rely=0.5, anchor=CENTER)

Notice that the parameter anchor is referencing the a relative position to the object (in this case button). anchor is not referencing to a position in the window. You could think that the button is a ship that has several anchors so you should choose a coordinate and which anchor you want to fix in that coordinate.

Example using .place():

from tkinter import *  # Use this if use python 3.xx
#from Tkinter import *   # Use this if use python 2.xx
a = Button(text="Center Button")
b = Button(text="Top Left Button")
c = Button(text="Bottom Right Button")

# You can use the strings the referencing the relative position on the button
# strings = n, ne, e, se, s, sw, w, nw, c or center
# Or you can use the constants of tkinter
# N, NE, E, SE, S, SW, W, NW, CENTER
a.place(relx=0.5, rely=0.5, anchor=CENTER)
b.place(relx=0.0, rely=0.0, anchor=NW)
c.place(relx=1.0, rely=1.0, anchor=SE)
mainloop()

Answer from Adolfo Correa on Stack Overflow
Top answer
1 of 3
33

To center horizontally this should be enough

button.pack(side=TOP)

But to center horizontally and vertically you could use nested frames. Check the following script:

import tkinter as tk

#%% Frames
frameA = tk.Frame(background="#c8c8c8")
frameB = tk.Frame(width=200, height = 200, background="#646464")
# Nested Frame. framebb is created within frameB without width or height
framebb = tk.Frame(frameB, background="#646464")
frameC = tk.Frame(width=100, height = 100, background="bisque")

frameA.pack(side='top', fill=None)
frameB.pack(side='top')
# expand is the key parameter to center the framebb within frameB
framebb.pack(expand=True)
frameC.pack(side='bottom')

#frameA.pack_propagate(False)
frameB.pack_propagate(False)
frameC.pack_propagate(False)

#%% Buttons and Labels
tk.Label(frameA, text = "Text within the frame A").pack()

a = tk.Button(framebb, text = "A").pack()
b = tk.Button(framebb, text = "B").pack()
c = tk.Button(framebb, text = "C").pack()
d = tk.Button(frameC, text = "D").pack()
e = tk.Button(frameC, text = "E").pack()

tk.mainloop()

Another approach could be using the .grid() method

button.grid(row=1,col=0)

the values of row=1,col=0 depend of the position of the other widget in your window

or you can use .place(relx=0.5, rely=0.5, anchor=CENTER)

button.place(relx=0.5, rely=0.5, anchor=CENTER)

Notice that the parameter anchor is referencing the a relative position to the object (in this case button). anchor is not referencing to a position in the window. You could think that the button is a ship that has several anchors so you should choose a coordinate and which anchor you want to fix in that coordinate.

Example using .place():

from tkinter import *  # Use this if use python 3.xx
#from Tkinter import *   # Use this if use python 2.xx
a = Button(text="Center Button")
b = Button(text="Top Left Button")
c = Button(text="Bottom Right Button")

# You can use the strings the referencing the relative position on the button
# strings = n, ne, e, se, s, sw, w, nw, c or center
# Or you can use the constants of tkinter
# N, NE, E, SE, S, SW, W, NW, CENTER
a.place(relx=0.5, rely=0.5, anchor=CENTER)
b.place(relx=0.0, rely=0.0, anchor=NW)
c.place(relx=1.0, rely=1.0, anchor=SE)
mainloop()

2 of 3
1

this is slightly old now, you have to do this:

import tkinter as tk #you can do 'from tkinter import *', any is fine
btn = tk.Button(text = "Centered Button")
btn.place(relx=0.5, rely=0.5, anchor='center')
๐ŸŒ
ActiveState
activestate.com โ€บ home โ€บ resources โ€บ quick read โ€บ how to position buttons in tkinter with place
How To Position Buttons In Tkinter With Place (Demo and Codes) - ActiveState
January 24, 2024 - There are four padding options you can use: ... For more information, refer to How To Use Pack in Tkinter. ... The simplest way to center a frame using Tkinter is to use the place() function, which allows you to use relative or absolute positioning.
๐ŸŒ
Tkinter
tkinter.com โ€บ center-widgets-with-place-python-tkinter-gui-tutorial-191
Center Widgets With Place โ€“ Python Tkinter GUI Tutorial 191 โ€“ TKinter.com
September 14, 2021 - from tkinter import * root = Tk() root.title('Codemy.com - Center A Thing With Place') root.iconbitmap('c:/gui/codemy.ico') root.geometry("500x500") button_1 = Button(root, text="Button 1", font=("Helvetica", 32)) button_2 = Button(root, text="Button 2", font=("Helvetica", 32)) button_1.grid(column=0, row=0) button_2.grid(column=1, row=0) my_button = Button(root, text="Click Me", font=("Helvetica, 32")) my_button.place(relx=0.5, rely=0.5, anchor=CENTER) #my_button.place(x=100, y=50) root.mainloop()
๐ŸŒ
DaniWeb
daniweb.com โ€บ programming โ€บ software-development โ€บ threads โ€บ 424169 โ€บ tkinter-center-a-grid-of-buttons
python - Tkinter - center a grid of buttons | DaniWeb
May 25, 2012 - Leaving sticky unset centers each button in its grid cell; the container itself is centered in the window. padx/pady give spacing; you do not need to compute pixel offsets. If you prefer pack, container.pack(expand=True) also centers the frame.
๐ŸŒ
Reddit
reddit.com โ€บ r/pythonhelp โ€บ [python -> tkinter] how to center buttons across the screen and is there a guide on how to position widgets?
r/pythonhelp on Reddit: [Python -> tkinter] How to center buttons across the screen and is there a guide on how to position widgets?
December 17, 2023 -

This part of the application is to allow you to replicate the full application and view the problem

from tkinter import *
from tkinter import Tk, 
Label, Button, Canvas
def clear_window(): 
    for widget in window.winfo_children(): 
    widget.destroy()

def MenuWindow(): 
    clear_window() 
    MenuBox("Title")

def PasswordManagerWindow(): 
    clear_window() 
    MenuBox("Password Manager")

def BlackmagicManualWindow(): 
    clear_window() 
    MenuBox("Blackmagic ATEM Software Control Manual")

def XSplitManualWindow(): 
    clear_window() 
    MenuBox("XSplit Manual")

The idea is to have the label directly under the horizontal buttons on the left side of the screen. The issue is that the configuration of the widgets is not aligned and can't place it on the grid system. [label button |-> (under these elements) Entry

def YouTubeManualWindow():
clear_window()
    MenuBox("YouTube Manual")
    labelStreamingApplication = Label(window, text = "Streaming Application").pack(side="left", padx=10)
    info = Button(window, text = "?").pack(side="left", padx=10)
    StreamingApplicationName = Entry(window, text = "Application Name").pack(side="top", pady=10)

The concept is to have this element disconnected from other widgets and not have the button's position effected by other widgets size or position. And possibly have the box have a different color

def MenuBox(title):
    menuFrame = Frame()
    menuFrame.place(relx=0.5, rely=0.5, anchor='center')
    titleText = Label(window, text=title, font = ('Times 12 bold')).pack()
    menuButton = Button(window, text="Menu",command = MenuWindow).pack(pady=5, side="top")
    passwordManager = Button(window, text="Password Manager",command = PasswordManagerWindow).pack(pady=5, side="top")
    blackmagicManual = Button(window, text="Blackmagic ATEM Software Control Manual",command = BlackmagicManualWindow).pack(pady=5, side="top")
    xSplitManual = Button(window, text="XSplit Manual",command = XSplitManualWindow).pack(pady=5, side="top")
    youTubeManual = Button(window, text="YouTube Manual",command = YouTubeManualWindow).pack(pady=5, side="top")

build

window = Tk()
window.title("Title")
 window.geometry("600x600") 
MenuWindow() 
window.mainloop()

๐ŸŒ
Python Forum
python-forum.io โ€บ thread-28358.html
Centering labels and buttons
Hello Python Users: I am a beginner with Python & Tkinter. I created 3 rows of labels and command buttons with the following code. I am kind of happy with the middle row. Sorry I couldn't figure out how to copy the screen so I could show you the ...
Find elsewhere
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ python โ€บ how-to-move-a-tkinter-button
How to move a Tkinter button? - GeeksforGeeks
July 23, 2025 - By default, with sticky='', widget is centered in its cell. sticky may be the string concatenation of zero or more of N, E, S, W, NE, NW, SE, and SW, compass directions indicating the sides and corners of the cell to which widget sticks.
๐ŸŒ
ActiveState
activestate.com โ€บ home โ€บ resources โ€บ quick read โ€บ how to position buttons in tkinter
How to Position Buttons in Tkinter - with Grid, Place or Pack - ActiveState
January 24, 2024 - Learn how to position buttons using three different geometric methods: pack, grid and place, with Python's GUI application Tkinter.
๐ŸŒ
TutorialsPoint
tutorialspoint.com โ€บ setting-the-position-on-a-button-in-tkinter-python
Setting the position on a button in Tkinter Python?
April 22, 2021 - Try the following example by moving cursor on different buttons โˆ’ ยท from tkinter import * top = Tk() L1 = Label(top, text="Physics") L1.place(x=10,y=10) E1 = Entry(top, bd =5) E1.place(x=60,y=10) L2=Label(top,text="Maths") L2.place(x=10,y=50) E2=Entry(top,bd=5) E2.place(x=60,y=50) L3=Label(top,text="Total") L3.place(x=10,y=150) E3=Entry(top,bd=5) E3.place(x=60,y=150) B = Button(top, text ="Add") B.place(x=100, y=100) top.geometry("250x250+10+10") top.mainloop()
๐ŸŒ
TutorialsPoint
tutorialspoint.com โ€บ how-to-horizontally-center-a-widget-using-a-grid-in-tkinter
How to horizontally center a widget using a grid() in Tkinter?
By default, with sticky='', widget is centered in its cell. sticky may be the string concatenation of zero or more of N, E, S, W, NE, NW, SE, and SW, compass directions indicating the sides and corners of the cell to which widget sticks.
๐ŸŒ
Tutorialspoint
tutorialspoint.com โ€บ python โ€บ tk_place.htm
Tkinter place() Method
Try the following example by moving cursor on different buttons โˆ’ ยท from tkinter import * top = Tk() L1 = Label(top, text="Physics") L1.place(x=10,y=10) E1 = Entry(top, bd =5) E1.place(x=60,y=10) L2=Label(top,text="Maths") L2.place(x=10,y=50) E2=Entry(top,bd=5) E2.place(x=60,y=50) L3=Label(top,text="Total") L3.place(x=10,y=150) E3=Entry(top,bd=5) E3.place(x=60,y=150) B = Button(top, text ="Add") B.place(x=100, y=100) top.geometry("250x250+10+10") top.mainloop()
๐ŸŒ
TutorialsPoint
tutorialspoint.com โ€บ how-to-center-a-tkinter-widget
How to center a Tkinter widget?
May 25, 2021 - #Import the required libraries from tkinter import * #Create an instance of Tkinter Frame win = Tk() #Set the geometry win.geometry("700x350") #Set the default color of the window win.config(bg='#4fe3a5') #Create a Label Label(win, text = "Hello World!", font= ('Helvetica 25 bold')).place(relx=.5, rely=.5,anchor= CENTER) win.mainloop()
๐ŸŒ
Python.org
discuss.python.org โ€บ python help
Button Placement Using '.grid' via tkinter - Python Help - Discussions on Python.org
October 23, 2023 - Hello, I am getting familiar with the tkinter package/library. In my test program, I would like to test the three different placement options using either pack, place, or grid. Using either the place or the pack optโ€ฆ
Top answer
1 of 3
51

Causing a widget to appear requires that you position it using with what Tkinter calls "geometry managers". The three managers are grid, pack and place. Each has strengths and weaknesses. These three managers are implemented as methods on all widgets.

grid, as its name implies, is perfect for laying widgets in a grid. You can specify rows and columns, row and column spans, padding, etc.

Example:

b = Button(...)
b.grid(row=2, column=3, columnspan=2)

pack uses a box metaphor, letting you "pack" widgets along one of the sides of a container. pack is extremely good at all-vertical or all-horizontal layouts. Toolbars, for example, where widgets are aligned in a horizontal line, are a good place to use pack.

Example:

b = Button(...)
b.pack(side="top", fill='both', expand=True, padx=4, pady=4)`

place is the least used geometry manager. With place you specify the exact x/y location and exact width/height for a widget. It has some nice features such as being able to use either absolute or relative coordinates (for example: you can place a widget at 10,10, or at 50% of the widgets width or height).

Unlike grid and pack, using place does not cause the parent widget to expand or collapse to fit all of the widgets that have been placed inside.

Example:

b = Button(...)
b.place(relx=.5, rely=.5, anchor="c")

With those three geometry managers you can do just about any type of layout you can imagine.

2 of 3
16

astynax is right. To follow the example you gave:

MyButton1 = Button(master, text="BUTTON1", width=10, command=callback)
MyButton1.grid(row=0, column=0)

MyButton2 = Button(master, text="BUTTON2", width=10, command=callback)
MyButton2.grid(row=1, column=0)

MyButton3 = Button(master, text="BUTTON3", width=10, command=callback)
MyButton3.grid(row=2, column=0)

Should create 3 row of buttons. Using grid is a lot better than using pack. However, if you use grid on one button and pack on another it will not work and you will get an error.

Top answer
1 of 3
1

I made some changes to your code below that seems to center the buttons like you're looking for. I removed the fixed geometry, the window will size itself. You also were mixing pack and grid, which can cause headaches like this to occur. It is best to pick one method and stick with it. Giving the first column in the header Frame a weight of one will make the label expand to fill all available space, centering it in the column.

from tkinter import *

home = Tk()
home.title("Home Page")
# Removed fixed geometry
home.resizable(0,0)

header = LabelFrame(home, bg="#12a8e3")
content = LabelFrame(home, bg="white")

header.columnconfigure(0, weight=1) # Forces column to expand to fill all available space

title = Label(header, text="School Subjects Quiz", bg="#12a8e3", fg="white", font=("Ariel",35, "bold"), padx=10, pady=10)
title.grid(row=0, column=0, columnspan=3) # Changed from pack to grid for consistency

questionsButton = Button(content, text="Questions", padx=250, pady=150)
questionsButton.grid(row=1, column=0, columnspan=3, padx=50, pady=50)

accountButton = Button(content, text="Account", padx=150, pady=150)
accountButton.grid(row=2, column=0, padx=50, pady=50)

resourceButton = Button(content, text="Revision Resources", padx=150, pady=150)
resourceButton.grid(row=2, column=1, padx=50, pady=50)

header.grid(row=0, sticky='NSEW')
content.grid(row=1, sticky='NSEW')

home.mainloop()
2 of 3
1

A general rule of thumb is that you should always give a non-zero weight to at least one row and one column in every widget that uses grid to manage its children. You are doing that for the root window but you are not doing that for the content window.

If you don't give columns a weight, and the window is larger than it needs to be to contain its children, the extra space will go unused. That is what is happening here - there is extra space on the right side of the content frame which isn't being used.

In your case you appear to be wanting three columns. So that those three columns together will fill the window, you should give every column an equal weight, or at least columns 0 and 2. You have a lot of other padding going on so it's hard to tell precisely what you want.

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

If you want to guarantee that all three columns are the same width, you can use the uniform option. All columns (or rows) with the same value for this option will be the same size. It doesn't matter what the value is.

content.grid_columnconfigure((0,2), weight=1, uniform="anything")