1

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.

7
  • Please provide a minimal reproducible example. Commented Aug 29, 2023 at 0:10
  • In particular, where is the mainloop() call? Commented Aug 29, 2023 at 0:11
  • Try using loading.withdraw() to hide the Toplevel window then loading.deiconify() when object creation is complete. Commented Aug 29, 2023 at 1:14
  • @Barmar My code is way too long to upload including mainloop etc. I can edit it to be a simplified version if you'd like? Commented Aug 29, 2023 at 16:31
  • Yes, that's what we'd like -- that's what "minimal" means. Commented Aug 29, 2023 at 16:42

1 Answer 1

1

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()
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.