JasonVB JasonVB - 3 months ago 14
Python Question

Why does my Tkinter window sometimes not display at all?

My Tkinter window displays correctly most of the time, but then sometimes, randomly, doesn't display. It's a major pain. I've tried various things (such as leaving out any Pygame rendering during the Tkinter window construction) and I've confirmed the window coordinates are exactly the same when displayed, or not displayed. I've tried to

lift
the window, I've tried to
force_focus
on the window, but nothing is working.

Here is my code:

# Function to take a postcode and station using Tkinter:
def first_time_setup():
global test_w, test_r, default_colour

master = Tk()
master.withdraw()

master.overrideredirect(1)
back_img = PhotoImage(file=find_data_file('Outlooker_background.png'))
back_label = Label(master, image=back_img)
back_label.place(x=0, y=0, relwidth=1, relheight=1)
back_label.image = back_img

text_font = font.Font(family='Arial', size=12)
button_font = font.Font(family='Calibri Light', size=11, weight="bold")

master.columnconfigure(0, weight=3)
e_weather = Entry(master, font=text_font, width=15)
e_weather.grid(row=0, column=1, padx=5, pady=(15, 5), sticky=E)
b_weather = Button(master, text="TEST", font=button_font,
bg='light blue', command=lambda: test_weather(e_weather.get(), b_weather, b_done))
b_weather.grid(row=0, column=2, padx=(0, 15), pady=(12, 0), sticky=E)

e_rail = Entry(master, font=text_font, width=15)
e_rail.grid(row=1, column=1, padx=5, pady=5, sticky=E)
b_rail = Button(master, text="TEST", font=button_font,
bg='light blue', command=lambda: test_rail(e_rail.get(), b_rail, b_done))
b_rail.grid(row=1, column=2, padx=(0, 15), sticky=E)

b_done = Button(master, text="DONE", font=button_font, state=DISABLED,
bg='light blue', command=lambda: testing_done(master))
b_done.grid(row=2, column=2, padx=(0, 15), pady=10, sticky=E)

if first_time:
b_quit = Button(master, text="QUIT", font=button_font,
bg='light blue', command=lambda: sys.exit(0))
else:
b_quit = Button(master, text="EXIT", font=button_font,
bg='light blue', command=lambda: master.destroy())
pygame.draw.rect(screen, black, (223, 296, 417, 134))
pygame.display.flip()

b_quit.grid(row=2, padx=15, pady=10, sticky=W)
default_colour = b_quit.cget("background")

master.update_idletasks() # Update "requested size" from geometry manager
x = (master.winfo_screenwidth() - 417) / 2
y = (master.winfo_screenheight() - 134) / 2
master.geometry("417x134+%d+%d" % (x, y))
master.deiconify()
master.lift()
master.focus_force()
e_weather.focus_set()
master.mainloop()


As the window is displaying about half of the time, I consider my code to be fine, and this is possibly a fault with either Tkinter or even Windows? Does anybody know what is happening please?

EDIT: Here is the call to
first_time_setup
:

if first_time:
first_time_setup()

first_time = False


So any further calls will trigger the
else
statement within the function.

Answer Source

A lot of people have been asking this type of question lately where overrideredirect is involved. So here is a little longer response as to why it happens and (in this case) how you can potentially fix it. Once you execute the line master.overrideredirect(1), window managers don't send focus or other event messages to the window. What might solve your problem is to do master.overrideredirect(1) at the very end of your initialization. Note also, that once you execute the command, the window manager essentially ignores the window. Try this experiment with master.overrideredirect(1) and master.overrideredirect(0) separately. Once the window is rendered, use the <Alt-Tab> keys to cycle through the windows. Notice that when master.overrideredirect(1), the window does not show up in the window list to cycle through. Finally, if the user does <Alt-Tab> away from the window, there is no event sent to the application to detect this, and the user may have a very difficult time setting focus back on the window, depending on how many overlapping windows they have covering it.

Typically, it is unwise to have a borderless main window due to lack of user control of it. The reason overrideredirect exists is probably for enabling the creation of custom temporary utility and megawidgets like comboboxes and such.