Reputation: 135
Ive recently started using tkinter in python, and I was having trouble centering the window. I tried all the tips on this website, but whenever I try them, the window is like a line in the middle of the screen. I have widgets already on it, and it works fine without the centering, but I would really appreciate it if someone could help me solve my problem. This is what I have been trying so far.
root = Tk()
root.title("Password")
root.resizable(FALSE,FALSE)
mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)
w = mainframe.winfo_width()
h = mainframe.winfo_height()
ws = root.winfo_screenwidth()
hs = root.winfo_screenheight()
x = (ws/2) - (w/2)
y = (hs/2) - (h/2)
root.geometry('%dx%d+%d+%d' % (w, h, x, y))
Upvotes: 4
Views: 13297
Reputation: 350
Hopefully someone will find use of this code, basically this is a solution you can use to center a TopLevel window relative to master (parent) window. Probably not the cleanest solution, but it will get the work done.
from Tkinter import *
class PasswordDialog(Toplevel):
def __init__(self, master=None):
Toplevel.__init__(self, master)
self.master = master
self.title("Password")
self.label_info = Label(self, text="You need to enter your password", pady=10)
self.label_info.grid(row=0, column=0, columnspan=2, padx=20, pady=10, sticky="ew")
self.label_pw = Label(self, text="Enter password:", pady=10)
self.label_pw.grid(row=1, column=0, padx=(20, 2), sticky="e")
self.entry = Entry(self, show="*")
self.entry.bind("<KeyRelease-Return>", self.store_pass_event)
self.entry.grid(row=1, column=1, padx=(2,20), sticky="w")
self.button = Button(self, command=self.store_pass, text="Log in")
self.button.grid(row=2, column=0, columnspan=2, pady=10)
self.update()
size = tuple(int(_) for _ in self.geometry().split('+')[0].split('x'))
parent_offset = tuple(int(_) for _ in self.master.geometry().split('x')[1].split('+'))
parent_width = self.master.winfo_width()
parent_height = self.master.winfo_height()
x = parent_width//2 - size[0]//2 + parent_offset[1]
y = parent_height//2 - size[1]//2 + parent_offset[2]
self.geometry("+%d+%d" % (x, y))
def store_pass_event(self, event):
self.store_pass()
def store_pass(self):
self.master.password = self.entry.get()
self.destroy()
Upvotes: -1
Reputation: 135
Ok I have found and fixed the problem. Piggybacking off of OregonTrail's solution, i found that if the window is the right size and you just want to change the location, then you can easily instead of setting the root's size, you can just move the window to the center.
w = root.winfo_reqwidth()
h = root.winfo_reqheight()
ws = root.winfo_screenwidth()
hs = root.winfo_screenheight()
x = (ws/2) - (w/2)
y = (hs/2) - (h/2)
root.geometry('+%d+%d' % (x, y)) ## this part allows you to only change the location
I think that this answer isn't exactly in the center, probably off by a little since h was returning 200 when it should be less, but it looks to be at the center and works fine.
Upvotes: 4
Reputation: 9039
You need to use winfo_reqwidth()
and winfo_reqheight()
, because the window does not have a height or width at the time that you call winfo_height()
and winfo_width()
.
An example program:
from tkinter import Tk
from tkinter import ttk
root = Tk()
style = ttk.Style()
style.configure("BW.TLabel", foreground="black", background="white")
l1 = ttk.Label(text="This is the best label in the world", style="BW.TLabel")
l1.pack()
w = l1.winfo_reqwidth()
h = l1.winfo_reqheight()
ws = root.winfo_screenwidth()
hs = root.winfo_screenheight()
x = (ws/2) - (w/2)
y = (hs/2) - (h/2)
print(w, h, x, y)
root.geometry('%dx%d+%d+%d' % (w, h, x, y))
root.mainloop()
Upvotes: 3