Как сделать загрузочный экран в 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 шт):

Автор решения: GravyTalk

Проблема, с которой вы столкнулись, заключается в том, что вы вызываете 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
→ Ссылка