hfaulkner
hfaulkner

Reputation: 1

Python tkinter toplevel opens with a blank window, then after some time, opens all the widgets and formats correctly

I am creating a toplevel:

#Loading screen

main = Tk()

loading = Toplevel()

loading.title("Co-worker")
loading.iconbitmap(getcwd()+"/icons/appIcons/windowIcon.ico")
loading.config(bg="#758ECD")

mywidth = 275

imageLoc = f"{getcwd()}/icons/appIcons/appLogo.png"

img = Image.open(imageLoc)
wpercent = (mywidth/float(img.size[0]))
hsize = int((float(img.size[1])*float(wpercent)))
img = img.resize((mywidth,hsize), Image.LANCZOS)
image = ImageTk.PhotoImage(img)

imageLabel = Label(loading, image = image, style = "mainTitle.TLabel")
imageLabel.grid(row=0,column=0)

loadingBar = Progressbar(loading, orient = 'horizontal', mode = 'indeterminate', length = 250, style = "loading.Horizontal.TProgressbar")
loadingBar.grid(row=1,column=0,padx=10,pady=10)
loadingBar.start(10)

main.mainloop()

Then at the end of the code, I destroy the toplevel, once the main window has finished loading. (loading.destroy())

When the code runs, for a short amount of time, the toplevel opens like this, before loading with all of it's widgets correctly.

How can I fix this so that it doesn't flash white first?

For all that are saying this, I just didn't include my imports as the list is very long. I am importing all the widgets directly from tkinter.ttk.

Upvotes: 0

Views: 139

Answers (1)

Derek
Derek

Reputation: 2244

In order to display Progressbar with no or very little flicker, I'm using loading.withdraw() to hide Toplevel window while it's being created.

I've used after to complete Toplevel display and to start Progressbar. After is also used to create a time lag to simulate loading data, building GUI, etc.

I've also set 'loading' window as transient to guarantee it will display above 'main` window.

This works on Windows 10, Python 3.9.1

import os
import tkinter as tk
import tkinter.ttk as ttk
from PIL import Image, ImageTk

#Loading screen
icon = os.path.join(os.getcwd(), "icons", "appIcons", "windowIcon.ico")
imageLoc = os.path.join(os.getcwd(), "icons", "appIcons", "appLogo.png")

main = tk.Tk()
main.deiconify()

loading = tk.Toplevel()
loading.withdraw()
loading.transient(main)

loading.title("Co-worker")
loading.iconbitmap(icon)
loading.config(bg="#758ECD")

mywidth = 275

img = Image.open(imageLoc)
wpercent = (mywidth/float(img.size[0]))
hsize = int((float(img.size[1])*float(wpercent)))
img = img.resize((mywidth,hsize), Image.LANCZOS)
image = ImageTk.PhotoImage(img)

imageLabel = tk.Label(loading, image = image, style = "mainTitle.TLabel")
imageLabel.grid(row=0,column=0)

loadingBar = ttk.Progressbar(
    loading, orient = 'horizontal', mode = 'indeterminate', length = 250,
    style = "loading.Horizontal.TProgressbar")
loadingBar.grid(row=1,column=0,padx=10,pady=10)

def closer():
    loadingBar.stop()
    loading.destroy()

def complete():
    loading.deiconify()
    loading.wait_visibility()
    loadingBar.start(10)
    
# complete Toplevel
main.after(100, complete)
# replace GUI completion with 5 second delay
main.after(5100, closer)

main.mainloop()

Upvotes: 1

Related Questions