在 Tkinter 中制作更新加载栏(标签)时遇到问题

Trouble with making a updating loading bar (Label) in Tkinter

我正在对加载栏(标签)进行百分比更新,它应该会在我的程序启动时自动启动。当 'Loading bar' 达到 100% 时,'Loading bar' 应该被删除,程序的其余部分应该继续,尽管当我启动程序时,window 直到大约 5 点才响应秒。

number = 0
number1 = str(number)

Labe = tk.Label(root, width=10,bd=1, bg="#ADA5A5", font=("Arial Bold", 36), fg="White")
Labe.grid(row=0, column=0)

def work():
   global number1
   Labe['text'] = "Loading" + " " + number1 + "%"
   global number
   number = number + 1
   number1 = str(number)
   if number == 102:
      root.after(1000)
      print("end")
      Labe.grid_remove()

num = 101
for x in range(num):
    print("He")
    root.after(50, work)
    root.after(50)

#Adding stuff to root
rootHelloLabel = tk.Label(root, text="Ordering system, please sign in", bg="#7271AD",
                          fg="White", font=("Arial Bold", 40), width=48, height=2)
placeholder = tk.Label(root, text="", pady=20, bg="#ACAD71")
placeholder.grid(row=0, column=0)
rootHelloLabel.grid(row=1, column=0)

placeholder1 = tk.Label(root, text="", pady=70, bg="#ACAD71")
placeholder1.grid(row=2, column=0)
loginButton = tk.Button(root, pady=30, padx=80, text="Login", font=("Arial Bold", 27),
                        bg="#71AD90", fg="#D0CFD1", command=login)
loginButton.grid(row=3, column=0)

adminButton = tk.Button(root, pady = 10, padx = 40, text="Admin", 
                        font=("Arial Bold", 27), bg="#71AD90", fg="#D0CFD1")
adminButton.grid(row=5, column=0)

我做了三个小改动,我认为它有效。

number = 0
number1 = str(number)

Labe = tk.Label(root, width=10,bd=1, bg="#ADA5A5", font=("Arial Bold", 36), fg="White")
Labe.grid(row=0, column=0)

def work():
   global number1
   Labe['text'] = "Loading" + " " + number1 + "%"
   global number
   number = number + 1
   number1 = str(number)
   if number == 102:
      root.after(1000)
      print("end")
      Labe.grid_remove()

num = 101
for x in range(num):
    print("He")
    root.after(50, work)
    root.after(50)
    root.update()  # added this so the window displays for one frame
# it's similar to mainloop() but only runs once

#Adding stuff to root
rootHelloLabel = tk.Label(root, text="Ordering system, please sign in", bg="#7271AD",
                          fg="White", font=("Arial Bold", 40), width=48, height=2)
placeholder = tk.Label(root, text="", pady=20, bg="#ACAD71")
placeholder.grid(row=0, column=0)
rootHelloLabel.grid(row=1, column=0)

placeholder1 = tk.Label(root, text="", pady=70, bg="#ACAD71")
placeholder1.grid(row=2, column=0)
loginButton = tk.Button(root, pady=30, padx=80, text="Login", font=("Arial Bold", 27),
                        bg="#71AD90", fg="#D0CFD1", command=lambda: login())
loginButton.grid(row=3, column=0)  # added lambda function so this only runs when clicked

adminButton = tk.Button(root, pady = 10, padx = 40, text="Admin", 
                        font=("Arial Bold", 27), bg="#71AD90", fg="#D0CFD1")
adminButton.grid(row=5, column=0)


root.mainloop()  # added this so that the program runs when done (can remove aswell)

我希望这对你有用。我不太明白这个问题,但是一旦我添加了 update() 函数,它就可以正常工作,我意识到你所说的加载栏是什么意思。希望对您有所帮助!

你在 for 循环中 运行s 100 次 after(50) 所以它可以停止程序 5 秒。而且我不知道你是否真的需要它。

我会 运行 after(50, work) 直接在 work

def work():
    global number   # PEP8: all `global` at the beginning of function

    labe['text'] = f"Loading {number}%"
    number += 1

    if number > 100:
        root.update() # to update last text in label because `after(1000)` will block it
        root.after(1000)
        print("end")
        labe.grid_remove()
    else:
        root.after(50, work)

完整的工作代码(有其他更改):

PEP 8 -- Style Guide for Python Code

import tkinter as tk

# --- functions ---   # PEP8: all functions directly after imports (and after all classes)

def work():
    global number   # PEP8: all `global` at the beginning of function

    labe['text'] = f"Loading {number}%"
    number += 1

    if number > 100:
        root.update() # to update last text in label because `after(1000)` will block it
        root.after(1000)
        print("end")
        labe.grid_remove()
    else:
        # run again
        root.after(50, work)
    
def login():
    pass

# --- main ---

number = 0

root = tk.Tk()

labe = tk.Label(root, width=10, bd=1, bg="#ADA5A5", font=("Arial Bold", 36), fg="White")
labe.grid(row=0, column=0)

root_hello_label = tk.Label(root, text="Ordering system, please sign in", bg="#7271AD",
                            fg="White", font=("Arial Bold", 40), width=48, height=2)
root_hello_label.grid(row=1, column=0)

placeholder1 = tk.Label(root, text="", pady=20, bg="#ACAD71")
placeholder1.grid(row=0, column=0)

placeholder2 = tk.Label(root, text="", pady=70, bg="#ACAD71")
placeholder2.grid(row=2, column=0)

login_button = tk.Button(root, pady=30, padx=80, text="Login", font=("Arial Bold", 27),
                         bg="#71AD90", fg="#D0CFD1", command=login)
login_button.grid(row=3, column=0)

admin_button = tk.Button(root, pady = 10, padx = 40, text="Admin", 
                         font=("Arial Bold", 27), bg="#71AD90", fg="#D0CFD1")
admin_button.grid(row=5, column=0)

# run first time
root.after(50, work)

root.mainloop()

编辑:

如果您需要 运行 和 for 循环,那么您应该在 after(..., work)

中设置不同的时间
for i in range(1, 102):
    root.after(50*i, work)

完整的工作代码:

import tkinter as tk

# --- functions ---   # PEP8: all functions directly after imports (and after all classes)

def work():
    global number   # PEP8: all `global` at the beginning of function

    labe['text'] = f"Loading {number}%"
    number += 1

    if number > 100:
        root.update() # to update last text in label because `after(1000)` will block it
        root.after(1000)
        print("end")
        labe.grid_remove()
    
def login():
    pass

# --- main ---

number = 0

root = tk.Tk()

labe = tk.Label(root, width=10, bd=1, bg="#ADA5A5", font=("Arial Bold", 36), fg="White")
labe.grid(row=0, column=0)

root_hello_label = tk.Label(root, text="Ordering system, please sign in", bg="#7271AD",
                            fg="White", font=("Arial Bold", 40), width=48, height=2)
root_hello_label.grid(row=1, column=0)

placeholder1 = tk.Label(root, text="", pady=20, bg="#ACAD71")
placeholder1.grid(row=0, column=0)

placeholder2 = tk.Label(root, text="", pady=70, bg="#ACAD71")
placeholder2.grid(row=2, column=0)

login_button = tk.Button(root, pady=30, padx=80, text="Login", font=("Arial Bold", 27),
                         bg="#71AD90", fg="#D0CFD1", command=login)
login_button.grid(row=3, column=0)

admin_button = tk.Button(root, pady = 10, padx = 40, text="Admin", 
                         font=("Arial Bold", 27), bg="#71AD90", fg="#D0CFD1")
admin_button.grid(row=5, column=0)

# 102-1 = 101 loops, because it needs to display values 0...100 which gives 101 values
for i in range(1, 102):  
    root.after(50*i, work)

root.mainloop()

编辑:

因为 after(1000) 冻结所有 GUI 1 秒,所以最好使用 after(1000, remove_label) 在 1 秒后执行其他功能,这不会冻结 GUI。

def work():
    global number

    labe['text'] = f"Loading {number}%"
    number += 1

    if number > 100:
        root.after(1000, remove_label)
    else:
        root.after(50, work)

def remove_label():
    print("end")
    labe.grid_remove()