Правильный подход заключается в использовании root.after
, при этом гарантируется, что несколько нажатий кнопок сбрасываются, когда индикатор выполнения активен:
Здесь мы используем аргумент ключевого слова со значением по умолчанию, чтобы определить, является ли звонок исходил от кнопки или от обратного вызова. Мы также храним идентификатор обратного вызова в замыкании, которое реализуется через изменяемый аргумент ключевого слова value по умолчанию; это позволяет нам полностью отменить дальнейшие обратные вызовы, когда работа будет завершена.
import tkinter as tk
import tkinter.ttk as ttk
def bar(btn=True, status=[None]):
"""activates and updates the progress bar status
while making sure that multiple button presses only
start it once.
"""
if btn and status[0] is not None:
return 'break'
elif pbar['value'] < 100:
pbar['value'], status[0] = pbar['value'] + 1, root.after(10, bar, False)
else:
root.after_cancel(status[0])
pbar['value'], status[0] = 0, None
root = tk.Tk()
pbar = ttk.Progressbar(root, orient=tk.HORIZONTAL, length=100, mode='determinate')
pbar.pack()
tk.Button(root, text='Start Bar', command=bar).pack()
root.mainloop()