具有更新标签的Tkinter加载屏幕

时间:2019-02-16 12:12:47

标签: python tkinter

我正在编写一个应用程序,该应用程序在启动时涉及大量数据处理。我想做的是创建一个启动屏幕,该屏幕实时告诉用户数据加载过程的哪个阶段。

我的计划是创建一个标签,然后根据当时进行的计算将新文本传递给该标签。但是,在我的各种尝试中,我所做的最好的事情就是让标签仅在完成调试后才显示。

我看到了这一点,这对我有所帮助,但仍然无法完全解决: Tkinter Show splash screen and hide main screen until __init__ has finished

以下是我目前的最佳尝试(将所有实际数据框的内容取出以使其最小可执行)

[编辑要添加]理想情况下,我想以不需要在类内部进行所有数据处理的方式来执行此操作。 IOW,第1阶段启动初始屏幕,第2阶段运行主代码中的数据处理,第3阶段启动主UI

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 :(得分:0)

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()