2

I would like my Tkinter Progressbar to update incrementally. I've tried following the examples mentioned here.

Originally, I tried the code without using threading. This resulted in a delay before the "Start" button even appeared. Once I added the threading part, the initial UI and the Progressbar widgets show up properly.

However, I'm still stuck on the problem where the Progressbar will not increment. Perhaps my Queue part of the code is breaking it? I've done some experiments, but the following is what I ended up with:

class MainUI:
    def __init__(self, master, queue):
        self.queue = queue
        self.master = master
        self.main_container = Frame(self.master)
        self.main_container.pack()
        self.counter = IntVar()
        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 prog_bar_update(self, value):
        self.counter = value

    def btn_start_click(self):    
        self.progress_bar()

    def process_queue(self):
        while self.queue.qsize():
            try:
                value = self.queue.get(0)
                self.prog_bar_update(value)
            except Queue.Empty:
                pass

class Logic:
    def __init__(self, master):
        self.master = master
        self.queue = Queue.Queue()
        self.gui = MainUI(master, self.queue)
        t = threading.Thread(target=self.start_logic)
        t.start()
        self.periodic_call()

    def periodic_call(self):
        self.gui.process_queue()
        self.master.after(100, self.periodic_call)

    def start_logic(self):
        for i in range(4):
            time.sleep(2)
            increment = i
            self.queue.put(increment)

root = Tk()
root.title("Progress Bar Test")
main_ui = Logic(root)
root.mainloop()

The above code results in the Progress bar showing up, but the increments never happen. I think I'm missing something very elementary and obvious here. Could someone please enlighten me?

4

1 回答 1

4

Take a look at this line of code:

self.counter = value

Prior to this line of code being executed, self.counter is an instance of IntVar. After this statement, self.counter is simply an int. Change the line to this:

self.counter.set(value)
于 2013-05-24T17:34:58.563 回答