I would like to make a GUI progress bar to show the progress of Joblib.
Here below is what I have done now:
import tkinter as tk
from tkinter import ttk
from tqdm import tqdm
from joblib import Parallel, delayed
def fun(_):
return _ ** 2
def main():
result = Parallel(n_jobs=-1, backend='threading')(delayed(fun)(_) for _ in tqdm(range(1024 ** 2)))
print(result)
root = tk.Tk()
progress_bar = ttk.Progressbar(root, mode='determinate')
progress_bar.pack()
button = tk.Button(root, text='start', command=main)
button.pack()
root.mainloop()
Now it is able to show the progress in the terminal with the tqdm
module. But I would like to ask, how can I make it to show the progress with the progress bar in tkinter window?
I have tried to call progress_bar.step()
in fun()
, but the program just freeze. Sorry that I am unfamiliar with tkinter.
I have kind of solved the question, but I know this is definitely not the best method. Here is my code:
import tkinter as tk
from tkinter import ttk
from tqdm import tqdm
from joblib import Parallel, delayed
from threading import Thread
n = 0
def fun(_):
global n
n += 1
return _ ** 2
def main():
def parallel():
nonlocal result
result = Parallel(n_jobs=-1, backend='threading')(delayed(fun)(_) for _ in range(1024 ** 2))
result = None
progress_bar['maximum'] = 1024 ** 2 # number of items that loops in Parallel
process = Thread(target=parallel, daemon=True)
process.start()
"""
update progress bar
"""
while progress_bar['value'] < 1024 ** 2:
progress_bar['value'] = n
root.update_idletasks()
root.update() # prevent freezing
process.join()
print(result)
root = tk.Tk()
progress_bar = ttk.Progressbar(root, mode='determinate')
progress_bar.pack()
button = tk.Button(root, text='start', command=main)
button.pack()
root.mainloop()
For this method, I have used a global variable n
to track the progress of Joblib. Also, it is important that the Joblib's task should be a subprocess, otherwise, it will freeze the tk
window. I know that using a global variable is not a good habit, but seems the overhead of a global variable in fun()
is not high. At least with this method, the progress bar is functionable.