我正在尝试在Toplevel小部件上显示一个进度条,然后每隔几秒逐步增加直到完成。
当我点击“开始”时,进度条小部件出现之前会有几秒钟的延迟。当它出现时,进度条根本不会增加。
这是我到目前为止所尝试的内容:
class MainUI:
def __init__(self, parent):
self.parent = parent
self.counter = IntVar()
self.main_container = Frame(self.parent)
self.main_container.pack()
self.btn_start = Button(self.main_container, command=self.btn_start_click)
self.btn_start.configure(
text="Start", background="Grey",
padx=50
)
self.btn_start.pack(side=LEFT)
def progress_bar(self):
self.pbar_top = Toplevel(self.main_container)
self.download_label = Label(
self.pbar_top,
text="Download Bar"
)
self.download_label.pack(side=TOP)
self.download_bar = ttk.Progressbar(
self.pbar_top, orient="horizontal",
length=400, mode="determinate",
variable=self.counter, maximum=5
)
self.download_bar.pack(side=TOP)
def btn_start_click(self):
self.progress_bar()
for i in range(4):
self.counter = i
time.sleep(1)
root = Tk()
root.title("Progress Bar Test")
main_ui = MainUI(root)
root.mainloop()
我发现在btn_start_click中注释掉for循环导致进度条在单击“开始”后立即出现。但是,和以前一样,实际的条形不会增加。
有人可以指出我做错了吗?
答案 0 :(得分:2)
问题是你在与Tkinter代码相同的线程中调用time.sleep(1)
。它使您的GUI无响应,直到任务(在这种情况下,对btn_start_click
的调用)完成。要解决此问题,您可以启动一个执行该功能的新线程,并使用Queue
之类的同步对象更新GUI线程中的进度条。 This is a working example我写了一个类似的问题。
此外,您应该调用self.counter.set(i)
而不是self.counter = i
来更新IntVar的值。另一个更明确的解决方案是self.download_bar.step()
,适当增量。
答案 1 :(得分:-1)
from tkinter import *
from tkinter import ttk
class MainUI:
def __init__(self, parent):
self.parent = parent
self.counter = IntVar()
self.main_container = Frame(self.parent)
self.main_container.pack()
self.btn_start = Button(self.main_container, command=self.startThread)
self.btn_start.configure(
text="Start", background="Grey",
padx=50
)
self.btn_start.pack(side=LEFT)
def progress_bar(self):
self.pbar_top = Toplevel(self.main_container)
self.download_label = Label(
self.pbar_top,
text="Download Bar"
)
self.download_label.pack(side=TOP)
self.download_bar = ttk.Progressbar(
self.pbar_top, orient="horizontal",
length=400, mode="determinate",
variable=self.counter, maximum=5
)
self.download_bar.pack(side=TOP)
def startThread(self):
import threading
def btn_start_click():
self.progress_bar()
for i in range(6):
self.counter.set(i)
import time
time.sleep(1)
t = threading.Thread(None, btn_start_click, ())
t.start()
root = Tk()
root.title("Progress Bar Test")
main_ui = MainUI(root)
root.mainloop()