0

Wanted to make a loading screen, no threads involved, just a class with init and 1 function. when I try to run it however it DOES WORK, just when i put my mouse on it or just wait long enough it says its 'unresponsive' and crashes.

Any ideas why?

Code:

class Loading_Screen:
    def __init__(self):
        self.root = Tk()
        self.root.title('Waiting for Connection...')
        self.root.config(bg = '#1F2700')
        self.root.geometry('800x400')

        theme = ttk.Style()
        theme.theme_use('winnative')
        theme.configure('orange.Horizontal.TProgressBar', background ='orange')

        loading_txt = Label(self.root, text = 'Waiting for Connection...', font = 'Teko 15', bg = '#1F2700')
        loading_txt.place(x=200, y =145)

        self.PBar = ttk.Progressbar(self.root,
                                    orient = 'horizontal', mode = 'indeterminate', length = 300)
        self.PBar.place(x=200, y=180)

        self.root.update()
        self.PBar_animation()

        self.root.mainloop()

    def PBar_animation(self):
        for i in range(0,2000):
            self.PBar['value'] +=1
            self.root.update_idletasks()
            sleep(0.1)
        self.root.destroy()
        exit(0)
Paul M.
  • 10,481
  • 2
  • 9
  • 15

2 Answers2

0

Thanks to Atlas435, I realized I needed to put the self.root.update() inside the animation function.

Fixed Code:

class Loading_Screen:
    def __init__(self):
        self.root = Tk()
        self.root.title('Waiting for Connection...')
        self.root.config(bg = '#1F2700')
        self.root.geometry('800x400')

        theme = ttk.Style()
        theme.theme_use('winnative')
        theme.configure('orange.Horizontal.TProgressBar', background ='orange')

        loading_txt = Label(self.root, text = 'Waiting for Connection...', font = 'Teko 15', bg = '#1F2700')
        loading_txt.place(x=200, y =145)

        self.start_Button = Button(self.root, text='Start connection', width=15,
                                 command=lambda: self.PBar_animation())
        self.start_Button.pack()
        self.PBar = ttk.Progressbar(self.root,
                                    orient = 'horizontal', mode = 'indeterminate', length = 300)
        self.PBar.place(x=200, y=180)

        self.root.mainloop()


    def PBar_animation(self):
        for i in range(0,2000):
            self.PBar['value'] +=1
            self.root.update_idletasks()
            self.root.update()
            sleep(0.1)
        self.root.destroy()
        exit(0)
acw1668
  • 40,144
  • 5
  • 22
  • 34
  • 2
    I realy have nothing to do with this code. I would [never](https://stackoverflow.com/questions/66781579/when-should-i-use-root-update-in-tkinter-for-python/66781785#66781785) recomand to use `.update()` Use the `after(ms, func)` instead, like in the posted [link](https://stackoverflow.com/a/51314379/13629335). – Thingamabobs Jun 06 '21 at 13:37
0

As @Atlas435 tried to tell you, it is better to use .after() instead of .update().

Instead of this:

def PBar_animation(self):
    for i in range(0, 2000):
        self.PBar['value'] +=1
        self.root.update_idletasks()
        sleep(0.1)
    self.root.destroy()
    exit(0)

use:

def PBar_animation(self, i=0):
    if i < 2000:
        self.PBar["value"] += 1
        self.root.after(100, self.PBar_animation, i+1)
    else:
        self.root.destroy()
        exit()

It uses a tkinter .after loop which acts just like a for loop.

The self.root.after(100, PBar_animation, i+1), calls self.PBar_animation() after 100 milliseconds with 1 argument: i+1. The default value of i is 0 when the function is first called.

TheLizzard
  • 7,248
  • 2
  • 11
  • 31