У меня есть небольшой тест GUI с кнопкой "Пуск" и панель "Прогресс". Желаемое поведение:
- Нажмите "Пуск"
- Progressbar колеблется в течение 5 секунд
- Индикатор Progressbar останавливается
Наблюдаемое поведение: кнопка "Старт" замерзает в течение 5 секунд, затем отображается индикатор прогресса (без колебаний).
Вот мой код:
class GUI:
def __init__(self, master):
self.master = master
self.test_button = Button(self.master, command=self.tb_click)
self.test_button.configure(
text="Start", background="Grey",
padx=50
)
self.test_button.pack(side=TOP)
def progress(self):
self.prog_bar = ttk.Progressbar(
self.master, orient="horizontal",
length=200, mode="indeterminate"
)
self.prog_bar.pack(side=TOP)
def tb_click(self):
self.progress()
self.prog_bar.start()
# Simulate long running process
t = threading.Thread(target=time.sleep, args=(5,))
t.start()
t.join()
self.prog_bar.stop()
root = Tk()
root.title("Test Button")
main_ui = GUI(root)
root.mainloop()
Основываясь на информации от Bryan Oakley здесь, я понимаю, что мне нужно использовать потоки. Я попытался создать поток, но я предполагаю, что, поскольку поток запускается из основного потока, это не помогает.
У меня возникла идея разместить логическую часть в другом классе и создать экземпляр GUI из этого класса, аналогичный примеру кода A. Rodas здесь.
Мой вопрос:
Я не могу понять, как закодировать его так, чтобы эта команда:
self.test_button = Button(self.master, command=self.tb_click)
вызывает функцию, расположенную в другом классе. Это плохое дело, или это даже возможно? Как создать 2-й класс, который может обрабатывать self.tb_click? Я пробовал следовать примеру кода А. Родаса, который прекрасно работает. Но я не могу понять, как реализовать его решение в случае виджета Button, который запускает действие.
Если я должен обработать поток из одного класса GUI, как создать поток, который не мешает основному потоку?