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()

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()

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')
Videos
I want to alagin 3 tk.Button objects right next to each other, centered in the screen horizontally, and at the top, under the other elements. I am pretty new at python, (started yesterday) but I can make a simple program, and couldn't find anything about this with Google, and ChatGPT messed up constantly, so help would be appreciated.
Thank you!
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()Actually in the previous semester I have also made some Tkinter application which is the project given by teacher to us. So I go to some tutorials website of Python and find three methods of placing the widgets on the output screen. The three methods are
1. Pack()
2. Grid()
3. Place() #the best method over Pack() and Grid()
Place() method take the coordinates in the form of the x and y. See this link for more clarification https://www.tutorialspoint.com/python/python_gui_programming.htm
https://www.tutorialspoint.com/python/tk_place.htm
See the bottom of the Page of the given link.The Place() method is defined with its proper arguments. I will prefer the Place() method over Pack() and Grid() because it works like CSS as we use in html, because it take the value of (width,height) and place your widget according to wherever you want.
If you find your answer a thumbs up will be appreciated.
Mine goes like this:
object1 = Tk()
actionBtn = Button(object1, text="Enter", width=15, height=2, command=quit).place(x=0, y=0)
#.place() is the best thing to use, x and y determine the location in terms of geometry.
you can even add an image with .png extension and goes like this:
buttonEnter = PhotoImage(file="buttonEnter.png") #image file must be inserted
buttonEnter1 = Button(object1, image=buttonEnter, width=20, height=4).place(x=0, y=0)
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.
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.
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()
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")