Как сделать загрузочный экран в Thinter python?
Всем привет. В моем приложении есть функция, которая выполняется слишком долго. Пока она работает я хочу показывать загрузочный экран.
def anim():
self.controller.show_frame("AnimationWindow")
while True:
if self.l[0]:
break
time.sleep(0.01)
def start_stream(self,data):
id=self.add_nameFrame()
self.l=[False]
threading.Thread(target=my_func,daemon=True).start()
self.anim()
Приложение работает верно, но не отображает фрейм "AnimationWindow", когда я таким способом вызываю фреймы в других случаях - все работает. Я использую систему контроллера, когда в окне просто меняются фреймы. Ссылка на описание системы. Функция anim работает, цикл прекращается в верное время.
Ответы (1 шт):
Проблема, с которой вы столкнулись, заключается в том, что вы вызываете self.anim() в основном потоке, что блокирует основной поток выполнения (где обновляется GUI) до тех пор, пока функция не завершится. Чтобы решить эту проблему, нужно запускать анимацию и отслеживать завершение процесса в отдельных потоках, чтобы основной поток мог обновлять GUI.
Вот несколько способов решить эту проблему:
Вариант 1: Использование threading Здесь мы запускаем анимацию и основной процесс в отдельных потоках.
import threading
import time
def anim(self):
self.controller.show_frame("AnimationWindow")
while True:
if self.l[0]:
break
time.sleep(0.01)
def start_stream(self, data):
id = self.add_nameFrame()
self.l = [False]
def run_my_func():
my_func() # Ваша долгая функция
self.l[0] = True # Сигнал о завершении
threading.Thread(target=run_my_func, daemon=True).start()
threading.Thread(target=self.anim, daemon=True).start()
Вариант 2: Использование tkinter и after Этот метод лучше подходит для работы с tkinter, так как позволяет использовать метод after для периодической проверки состояния.
import threading
import time
import tkinter as tk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.l = [False]
def anim(self):
self.controller.show_frame("AnimationWindow")
self.check_status()
def check_status(self):
if self.l[0]:
self.controller.show_frame("MainFrame") # Показываем основной фрейм после завершения
else:
self.after(10, self.check_status) # Проверяем статус через 10 мс
def start_stream(self, data):
id = self.add_nameFrame()
self.l = [False]
def run_my_func():
my_func() # Ваша долгая функция
self.l[0] = True