Экран загрузки Tkinter с обновлением меток - PullRequest
0 голосов
/ 16 февраля 2019

Я пишу приложение, которое требует значительного количества данных при запуске.То, что я хотел бы сделать, это создать заставку, которая сообщает пользователю, какой этап процесса загрузки данных происходит в режиме реального времени.

Мой план состоял в том, чтобы создать метку и передать новый текст этой метке в зависимости от того, какие вычисления происходили в этот момент.Однако в моих различных попытках лучшее, что я сделал, - заставил ярлыки показываться только после того, как munging завершился.

Я видел это, что мне немного помогло, но все еще не получилось полностью: Tkinter Показать заставку и скрыть главный экран, пока __init__ не закончится

Ниже приведена моя лучшая попытка (вытащить весь фактический материал с кадрами, чтобы сделать его минимально исполняемым)

[РЕДАКТИРОВАТЬ, ДОБАВИТЬ] В идеале я хотел бы сделать это таким образом, чтобы не требовалось, чтобы все данные обрабатывались внутри класса.IOW, фаза 1 запускает заставку, фаза 2 запускает группирование данных в основном коде, фаза 3 запускает основной пользовательский интерфейс

import time
from tkinter import *

class LoadScreen(Toplevel):
    def __init__(self, parent):
        Toplevel.__init__(self, parent)
        self.title('Loading')
        self.update()

class UserInterface(Tk):
    def __init__(self, parent):
        Tk.__init__(self, parent)
        self.parent=parent
        self.withdraw()
        loader = LoadScreen(self)
        self.load_label = Label(loader, text='Loading')
        self.load_label.grid(row=0, column=0, padx=20, pady=20)
        self.stage_label = Label(loader, text='Preparing dataframe')
        self.stage_label.grid(row=1, column=0, padx=20, pady=20)
        #loader.destroy()
        self.main_screen()

    def main_screen(self):
        self.deiconify()
        self.load_label = Label(self, text='Done')
        self.load_label.grid(row=0, column=0, padx=20, pady=20)
        self.close_button = Button(self, text='Close', 
            command = lambda: self.destroy())
        self.close_button.grid(row=1, column=0, padx=20, pady=20)

ui = UserInterface(None)

#Pretend I'm doing some dataframe munging
print('1')
time.sleep(2)
ui.stage_label['text'] = 'Running some calculations'
print('2')
time.sleep(2)
ui.stage_label['text'] = 'Finishing up'
print('3')
time.sleep(2)

ui.mainloop()

1 Ответ

0 голосов
/ 16 февраля 2019

time.sleep заблокирует основной поток.Вот минимальный пример того, как я обычно это делаю.

import time
from tkinter import *

root = Tk()
root.withdraw()
Label(root,text="I am main window").pack()

class SplashScreen:
    def __init__(self):
        self.a = Toplevel()
        self.percentage = 0
        Label(self.a,text="I am loading screen").pack()
        self.load = Label(self.a,text=f"Loading...{self.percentage}%")
        self.load.pack()
        self.load_bar()

    def load_bar(self):
        self.percentage +=5
        self.load.config(text=f"Loading...{self.percentage}%")
        if self.percentage == 100:
            self.a.destroy()
            root.deiconify()
            return
        else:
            root.after(100,self.load_bar)

SplashScreen()

root.mainloop()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...