居中TopLevel窗口,保持栅格/包装几何的动态尺寸?

时间:2019-05-24 03:59:19

标签: python python-3.x tkinter

我想将TopLevel窗口居中到其父窗口(TkTopLevel窗口)的中间。问题是我想保持窗口{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()

如果任何人都知道如何做到这一点,而没有在屏幕上闪烁窗口,那将是一个很大的帮助。 :)

1 个答案:

答案 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)
...