我想将TopLevel
窗口居中到其父窗口(Tk
或TopLevel
窗口)的中间。问题是我想保持窗口{t1inter的几何管理器.pack()
和.grid()
给出的窗口的动态大小(窗口的大小取决于所需的大小)。
我想不必使用update()
来执行此操作,我知道这可以解决我的问题,因为我不希望窗口闪烁,然后快速闪烁到它应该位于的位置
到目前为止,这是我最好的尝试,问题是它消除了 动态调整大小。
from tkinter import *
def center_to_win(window, master):
x = master.winfo_x()
y = master.winfo_y()
w = window.winfo_reqwidth()
h = window.winfo_reqheight()
total_x = x + (master.winfo_width() // 2) - (w // 2)
total_y = y + (master.winfo_height() // 2) - (h // 2)
window.geometry("%dx%d+%d+%d" % (int(w), int(h), int(total_x), int(total_y)))
class MainWin(Tk):
def __init__(self):
super(MainWin, self).__init__()
self.update()
pu = PopUp(self)
class PopUp(Toplevel):
def __init__(self, master):
super(PopUp, self).__init__(master)
for i in range(20):
label = Label(self, text="label i")
label.grid(column=0, row=i)
center_to_win(self, master)
if __name__ == '__main__':
win = MainWin()
win.mainloop()
如果任何人都知道如何做到这一点,而没有在屏幕上闪烁窗口,那将是一个很大的帮助。 :)
答案 0 :(得分:2)
据我所知,在update()
执行之前没有mainloop()
的窗口是不可能更新的。但是,可以在不隐藏窗口的情况下通过更新窗口来完成此操作。 我们可以使用window.wm_withdraw()
隐藏并使用window.wm_deiconify()
显示,至少在我的系统上延迟不明显。 window.iconify()
也可以代替window.wm_withdraw()
使用,但它不能与transient()
一起使用。
可以使用功能center_to_win()
将一个窗口集中在另一个窗口上。
def center_to_win(window, master):
window.wm_withdraw()
window.update()
x = master.winfo_x()
y = master.winfo_y()
w = window.winfo_reqwidth()
h = window.winfo_reqheight()
total_x = x + (master.winfo_width() // 2) - (w // 2)
total_y = y + (master.winfo_height() // 2) - (h // 2)
window.geometry("%dx%d+%d+%d" % (int(w), int(h), int(total_x), int(total_y)))
window.wm_deiconify()
仅通过center_to_win(self, master)
调用该函数就可以很好地工作,但是我注意到一个问题,当您在开始时设置主窗口的几何形状时,可以通过调用类似self.after(1, center_to_win, self, master)
的函数来解决该问题。尽管它是非常随机的,并且可能不会发生在您身上,但是如果有的话,请使用after(..)
。
动态调整大小。
尽管这解决了动态调整大小的问题,但是您应该对{em> grid 布局使用self.grid_rowconfigure(index, weight=1)
和self.grid_columnconfigure(index, weight=1)
。
...
for i in range(20):
self.grid_rowconfigure(i, weight=1)
label = Label(self, text="label i")
label.grid(column=0, row=i)
...