在确定模式下使用ttk.Progressbar

时间:2013-05-23 20:02:03

标签: python python-2.7 tkinter ttk

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

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

2 个答案:

答案 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()