1

我试图让一个进度条出现在 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 循环会导致进度条在单击“开始”后立即出现。但是,和以前一样,实际柱不会增加。

有人可以指出我做错了什么吗?

4

2 回答 2

2

问题是您time.sleep(1)在与 Tkinter 代码相同的线程中调用。它使您的 GUI 在任务(在本例中为对 的调用btn_start_click)完成之前没有响应。为了解决这个问题,您可以启动一个执行该函数的新线程,并使用同步对象(如Queue. 这是我为类似问题编写的一个工作示例。

此外,您应该调用self.counter.set(i)而不是self.counter = i更新 IntVar 的值。另一个更明确的解决方案是self.download_bar.step()适当的增量。

于 2013-05-23T20:14:39.187 回答
-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()
于 2014-12-21T12:11:40.483 回答