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()
Answer from Bryan Oakley on Stack OverflowThere'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()
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.
Videos
Iโve coded a wordle GUI using Tkinter. I wonโt include all the code as itโs ~600 lines, but the main problem revolves around the following code (sorry, idk how to make it an actual code box in Reddit):
widget = Label(root, text = โ โ, font = (โArielโ, 25)) widget.grid(column = 4, row = 4)
This will make my label, set the parameters, and then align it with the GUI grid.
It all works great except for one thing - the text box displaying โThe word was โ_____โ!โ pushes all the other widgets to the side. I KNOW this is because Iโm using button.grid() to set the locations of all of the buttons, and when the text is finally updated in that text box (changes from โ โ to the above text), it makes the width much larger than the other center widgets.
Is there a way within Tkinter to get it to โignoreโ the other widgets so it can be whatever width it wants to be without pushing the other widgets to the edges?
The problem is that none of your columns have any weight. It is the weight attribute that decides what columns (and rows) get any extra space. Since none of your columns have a non-zero weight, none of the extra space is allocated to them, so they stay as small as they can be.
As a rule of thumb, you should always give at least one row and one column in a frame a non-zero weight. In your case, giving row 0 and column 0 a weight of 1 for all of the frames seems to work:
self.root.grid_columnconfigure(0, weight=1)
self.root.grid_rowconfigure(0, weight=1)
self.contentFrame.grid_columnconfigure(0, weight=1)
self.contentFrame.grid_rowconfigure(0, weight=1)
self.topBar.grid_columnconfigure(0, weight=1)
self.topBar.grid_rowconfigure(0, weight=1)
by using 'how to make tkinter grid expand' in google i came across the problem.
quote from Bryan Oakley
Rows and columns have "weight" which describes how they grow or shrink to fill extra space >in the master. By default a row or column has a weight of zero, which means you've told the >label to fill the column but you haven't told the column to fill the master frame.
To fix this, give the column a weight.
class Test():
def __init__(self,root):
self.root = root
self.root.columnconfigure(0, weight=1)
self.root.config(bg='green')
self.message = 'test message'
self.contentFrame = Frame(self.root)
self.contentFrame.config(background='black',borderwidth=5,relief ='sunken')
self.contentFrame.grid(row=0, column=0, sticky='news')
self.contentFrame.columnconfigure(0, weight=1)
self.topBar = Frame(self.contentFrame, border=2, relief=RAISED)
self.topBar.grid(row=0, column=0, columnspan=23,sticky=W+E)
self.topBar.config(background='blue')
self.topBar.columnconfigure(0, weight=1)
self.newGameButton = Button(self.topBar, text="New Game")
self.newGameButton.grid(row=0, column=0)
self.newGameButton.config(background='red')
self.messageBox = Label(self.topBar, text=self.message, height=2)
self.messageBox.grid(row=1, column=0, columnspan=1,sticky=W+E)
self.messageBox.config(background='yellow')
Test(root)