I am writing a Tkinter app and i need an indeterminate progressbar that shows over the main window, while, in the back, the function called does some operations. Because i don't know how long this operation will be, i don't want to have to time the progress bar. Also, the function called will show an info window, so, there should the progressbar stop. I've looked up multiple ways of doing it, and i think i found the right method. I want to let the function to run in a separate thread, measure the thread execution time, and then pass the time, somehow, to the progressbar to stop. I don't know if this is the right way. Also, it doesn't work, mostly because i don't know what i am doing, because is my first time working with threads. Below is my code:
- the progress bar:
def loading_page(time):
def close_loading():
root.destroy()
root = tk.Tk()
root.title("Loading Page")
root.resizable(False, False)
loading_label = ttk.Label(root, text="Loading...", font=("Montserat", 12))
loading_label.pack(pady=15, padx=15)
progress_bar = ttk.Progressbar(root, length=200, mode="indeterminate")
progress_bar.pack(padx=15, pady=15)
progress_bar.after(time, close_loading())
progress_bar.start(10)
root.mainloop()
- the threads:
def task(*args):
loading_page(*args)
def thread_time_decorator(thread):
@wraps(thread)
def wrapper(*args, **kwargs):
start = time.perf_counter()
thread(*args, **kwargs)
end = time.perf_counter()
threading.current_thread().thread_duration = end - start
return wrapper
def worker(func, *args):
t1 = threading.Thread(target=func, args=(*args,))
t1.start()
def ini_task(c):
t1 = threading.Thread(target=generate_file, args=(c,))
wrapped_t1 = thread_time_decorator(t1)
t1.start()
task(wrapped_t1)
t1.join()
- the function that will be called from the main window:
def some_function(c):
with contextlib.suppress(Exception):
helper.close_one_drive()
try:
#some file operations
except Exception:
if kill_prompt := messagebox.askokcancel(
title="Excel about to close",
message="This operation cannot be performed because the file is already opened."
"\n If you press 'OK' to continue the process, all opened Excel files will be closed.",
):
os.system("taskkill /T /IM EXCEL.exe")
file_gen = some_function(c)
#this is where the progress bar shoud stop, or be destroyed immediately after the whole function finishes
if prompt := messagebox.askokcancel(
title=f"Operation complete for {c}",
message=f" Would you like to go to {c} ?",
):
return c, subprocess.call(
[file_gen],
shell=True,
)