Look at this function:
def calculate_sync(self): max = 3000000 for i in range(1, max): self.progressbar["value"] = i / max * 100
When this function is executed synchronously, the GUI freezes.
By clicking the 'Calculate Sync' button, the function is called and the GUI freezes. After a few seconds, the progress bar is 100% full and the GUI gets responsive again.
But what you want, is that the function runs while updating the UI.
This time, the 'Calculate Async' button is clicked and the function executes asynchronously and the GUI stays responsive.
The following code creates an app that creates a window. The window gets the asyncio event loop.
__init__ creates a window and the show function creates an infinite loop that calls self.root.update(). update() keeps the GUI event loop running.
import tkinter as tk from tkinter import ttk import asyncio class App: async def exec(self): self.window = Window(asyncio.get_event_loop()) await self.window.show(); class Window(tk.Tk): def __init__(self, loop): self.loop = loop self.root = tk.Tk() self.animation = "░▒▒▒▒▒" self.label = tk.Label(text="") self.label.grid(row=0, columnspan=2, padx=(8, 8), pady=(16, 0)) self.progressbar = ttk.Progressbar(length=280) self.progressbar.grid(row=1, columnspan=2, padx=(8, 8), pady=(16, 0)) button_block = tk.Button(text="Calculate Sync", width=10, command=self.calculate_sync) button_block.grid(row=2, column=0, sticky=tk.W, padx=8, pady=8) button_non_block = tk.Button(text="Calculate Async", width=10, command=lambda: self.loop.create_task(self.calculate_async())) button_non_block.grid(row=2, column=1, sticky=tk.W, padx=8, pady=8) async def show(self): while True: self.label["text"] = self.animation self.animation = self.animation[1:] + self.animation[0] self.root.update() await asyncio.sleep(.1) def calculate_sync(self): max = 3000000 for i in range(1, max): self.progressbar["value"] = i / max * 100 async def calculate_async(self): max = 3000000 for i in range(1, max): self.progressbar["value"] = i / max * 100 if i % 1000 == 0: await asyncio.sleep(0) asyncio.run(App().exec())
There is no need to install any third party library. Copy and paste this code and run it with Python to test it yourself.