How to do it...

To simulate the execution of a background task, the increment of the progress bar will be generated from a different thread that will suspend its execution for 1 second between each step.

The communication will be made using a synchronized queue that allow us to exchange information in a thread-safe manner:

import time
import queue
import threading
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.messagebox as mb

class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("Progressbar example")
self.queue = queue.Queue()
self.progressbar = ttk.Progressbar(self, length=300,
orient=tk.HORIZONTAL)
self.button = tk.Button(self, text="Start",
command=self.start_action)

self.progressbar.pack(padx=10, pady=10)
self.button.pack(padx=10, pady=10)

def start_action(self):
self.button.config(state=tk.DISABLED)
thread = AsyncAction(self.queue, 20)
thread.start()
self.poll_thread(thread)

def poll_thread(self, thread):
self.check_queue()
if thread.is_alive():
self.after(100, lambda: self.poll_thread(thread))
else:
self.button.config(state=tk.NORMAL)
mb.showinfo("Done!", "Async action completed")

def check_queue(self):
while self.queue.qsize():
try:
step = self.queue.get(0)
self.progressbar.step(step * 100)
except queue.Empty:
pass

class AsyncAction(threading.Thread):
def __init__(self, queue, steps):
super().__init__()
self.queue = queue
self.steps = steps

def run(self):
for _ in range(self.steps):
time.sleep(1)
self.queue.put(1 / self.steps)

if __name__ == "__main__":
app = App()
app.mainloop()
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset