Question

I'm trying to write a GUI for something long running and cant seem to figure out how to avoid locking the GUI thread. I want to use ttk.Progressbar but I cant seem to update the bar value and have the window update the GUI. I've tried putting the update handling in its own function and updating it directly but neither worked. Updating the value in a handler is what I'd prefer to do since this script would do some downloading, then processing, then uploading and three separate bars would look nicest.

from Tkinter import *
import time, ttk

class SampleApp(Frame):
    def __init__(self,master):
        Frame.__init__(self,master)
        self.pack()
        self.prog = ttk.Progressbar(self, orient = 'horizontal', length = 200, mode = 'determinate')
        self.prog.pack()
        self.button = Button(self,text='start',command=self.start)
        self.button.pack()

    def start(self):
        self.current = 0
        self.prog["value"] = 0
        self.max = 10
        self.prog["maximum"] = self.max
        self.main_prog()

    def handler(self):
        self.prog['value'] += 1

    def main_prog(self):
        for x in range(10):
            time.sleep(2)
            self.handler()

root = Tk()
app = SampleApp(master = root)
app.mainloop()
Was it helpful?

Solution

It is not the progressbar that's causing the lockup, but your call to time.sleep()

GUI toolkits use event loops to process user input. You are interrupting event processing with the sleep call.

There are several ways to handle long-running jobs in an event-driven program;

  1. Chop the job up into little pieces and handle each small piece in a timeout, using the after method of the root window.
  2. Handle the processing in a separate thread. Note that this thread should not call tkinter functions! And note that in cpython only one thread at a time can be processing bytecode due to the GIL.
  3. Handle the processing in a separate process using multiprocessing. Data is sent to and from that process using a Queue. The GUI program reads from the Queue and updates the GUI in a timeout.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top