简体   繁体   中英

Unable to hide Tkinter window while I am setting its geometry

I have a root window and I want to create a Toplevel window positioned in a specific place on the screen (centralized over the root window). So far I have been unable to accomplish this without seeing the Toplevel window quickly build itself in its default location and then hop over to the position I want it. I would prefer not to see this because it's weird and jarring.

Is there a way to build, then reposition a window in Tkinter without seeing it reposition itself?

Here's some example code with a sleep thrown in to simulate a complex window being rendered:

from tkinter import *
import time


def centralize_over_root(window_to_centralize):
    root_geometry = root.winfo_geometry()
    root_width_height = root_geometry.split('+')[0]
    root_width = root_width_height.split('x')[0]
    root_height = root_width_height.split('x')[1]
    root_x_y = root_geometry.split(f'{root_height}+')[1]
    root_x = root_x_y.split('+')[0]
    root_y = root_x_y.split('+')[1]
    window_to_centralize.update()
    time.sleep(0.5)
    window_width = window_to_centralize.winfo_width()
    window_height = window_to_centralize.winfo_height()
    window_x = int(root_x) + round((int(root_width) - int(window_width)) / 2.0)
    window_y = int(root_y) + round((int(root_height) - int(window_height)) / 2.0)
    result = f'+{window_x}+{window_y}'
    return result


def new_window():
    new_window = Toplevel(root)
    Label(new_window, text='Something').pack(padx=20, pady=20)
    new_window.geometry(centralize_over_root(new_window))


root = Tk()
Button(root, text='Make new window', command=new_window).pack(padx=50, pady=50)
root.mainloop()

I think the following will do what you want. There are comments showing where I made changes. The problem was the time.sleep() was interfering with the mainloop() and your window_to_centralize.update() which makes it appear before you're finished configuring it.

from tkinter import *
import time


def centralize_over_root(window_to_centralize):
    root_geometry = root.winfo_geometry()
    root_width_height = root_geometry.split('+')[0]
    root_width = root_width_height.split('x')[0]
    root_height = root_width_height.split('x')[1]
    root_x_y = root_geometry.split(f'{root_height}+')[1]
    root_x = root_x_y.split('+')[0]
    root_y = root_x_y.split('+')[1]
#    window_to_centralize.update()  # Don't do this - will happen automatically.
#    time.sleep(0.5)
    root.after(500)  # This pauses without interfering with mainloop.
    window_width = window_to_centralize.winfo_width()
    window_height = window_to_centralize.winfo_height()
    window_x = int(root_x) + round((int(root_width) - int(window_width)) / 2.0)
    window_y = int(root_y) + round((int(root_height) - int(window_height)) / 2.0)
    result = f'+{window_x}+{window_y}'
    return result


def new_window():
    new_window = Toplevel(root)
    Label(new_window, text='Something').pack(padx=20, pady=20)
    new_window.geometry(centralize_over_root(new_window))


root = Tk()
Button(root, text='Make new window', command=new_window).pack(padx=50, pady=50)
root.mainloop()

You can hide the window using withdraw() and show it after reposition using deiconify() :

def new_window():
    new_window = Toplevel(root)
    new_window.withdraw() # hide the window
    Label(new_window, text='Something').pack(padx=20, pady=20)
    new_window.geometry(centralize_over_root(new_window))
    new_window.deiconify() # show the window

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM