与 joblib 并行的 tkinter 进度条
tkinter progress bar with joblib parallel
我想制作一个GUI进度条来显示Joblib的进度。
下面是我现在所做的:
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()
现在可以使用 tqdm
模块在终端中显示进度。但是我想问一下,我怎样才能让它在tkinter中用进度条显示进度window?
我试图在 fun()
中调用 progress_bar.step()
,但程序只是冻结。抱歉,我对 tkinter 不熟悉。
我已经解决了这个问题,但我知道这绝对不是最好的方法。这是我的代码:
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()
对于这个方法,我使用了一个全局变量n
来跟踪Joblib的进度。另外,重要的是 Joblib 的任务应该是一个子进程,否则,它会冻结 tk
window。我知道使用全局变量不是一个好习惯,但是 fun()
中全局变量的开销似乎并不高。至少用这个方法,进度条是可以用的。
我想制作一个GUI进度条来显示Joblib的进度。
下面是我现在所做的:
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()
现在可以使用 tqdm
模块在终端中显示进度。但是我想问一下,我怎样才能让它在tkinter中用进度条显示进度window?
我试图在 fun()
中调用 progress_bar.step()
,但程序只是冻结。抱歉,我对 tkinter 不熟悉。
我已经解决了这个问题,但我知道这绝对不是最好的方法。这是我的代码:
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()
对于这个方法,我使用了一个全局变量n
来跟踪Joblib的进度。另外,重要的是 Joblib 的任务应该是一个子进程,否则,它会冻结 tk
window。我知道使用全局变量不是一个好习惯,但是 fun()
中全局变量的开销似乎并不高。至少用这个方法,进度条是可以用的。