Tkinter 显示初始屏幕并隐藏主屏幕,直到 __init__ 完成

Tkinter Show splash screen and hide main screen until __init__ has finished

我有一个主要的 tkinter window 可能需要几秒钟才能正确加载。正因为如此,我希望有一个闪屏显示,直到主 class 的 init 方法完成,并且可以显示主 tkinter 应用程序。如何实现?

启动画面代码:

from Tkinter import *
from PIL import Image, ImageTk
import ttk

class DemoSplashScreen: 
    def __init__(self, parent): 
        self.parent = parent 
        self.aturSplash() 
        self.aturWindow() 

    def aturSplash(self): 
        self.gambar = Image.open('../output5.png')
        self.imgSplash = ImageTk.PhotoImage(self.gambar)

    def aturWindow(self):
        lebar, tinggi = self.gambar.size 
        setengahLebar = (self.parent.winfo_screenwidth()-lebar)//2 
        setengahTinggi = (self.parent.winfo_screenheight()-tinggi)//2
        self.parent.geometry("%ix%i+%i+%i" %(lebar, tinggi, setengahLebar,setengahTinggi))
        Label(self.parent, image=self.imgSplash).pack()


if __name__ == '__main__': 
    root = Tk()
    root.overrideredirect(True) 
    progressbar = ttk.Progressbar(orient=HORIZONTAL, length=10000, mode='determinate') 
    progressbar.pack(side="bottom") 
    app = DemoSplashScreen(root) 
    progressbar.start()
    root.after(6010, root.destroy) 
    root.mainloop()

主要 tkinter window 最小工作示例:

import tkinter as tk

root = tk.Tk()

class Controller(tk.Frame):
    def __init__(self, parent):
        '''Initialises basic variables and GUI elements.'''
        frame = tk.Frame.__init__(self, parent,relief=tk.GROOVE,width=100,height=100,bd=1)

control = Controller(root)
control.pack()
root.mainloop()

编辑:我可以使用主要 window 直到它使用 .withdraw() 和 .deiconify() 方法完成加载。但是我的问题是我找不到在这两个方法调用之间的时间段内显示启动画面 运行 的方法。

python3的简单示例:

#!python3

import tkinter as tk
import time

class Splash(tk.Toplevel):
    def __init__(self, parent):
        tk.Toplevel.__init__(self, parent)
        self.title("Splash")

        ## required to make window show before the program gets to the mainloop
        self.update()

class App(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.withdraw()
        splash = Splash(self)

        ## setup stuff goes here
        self.title("Main Window")
        ## simulate a delay while loading
        time.sleep(6)

        ## finished loading so destroy splash
        splash.destroy()

        ## show window again
        self.deiconify()

if __name__ == "__main__":
    app = App()
    app.mainloop()

像这样的事情在 tkinter 中很困难的原因之一是 windows 仅在程序不是 运行 特定功能时才更新,因此到达主循环。对于像这样简单的事情,您可以使用 updateupdate_idletasks 命令使其成为 show/update,但是如果延迟太长,则在 windows 上 window可以变成"unresponsive"

解决此问题的一种方法是在整个加载例程中放置多个 updateupdate_idletasks 命令,或者使用线程。

但是,如果您使用线程,我建议您不要将 splash 放入它自己的线程(可能更容易实现),您最好将加载任务放入它自己的线程,保持工作线程和 GUI 线程分开,因为这往往会提供更流畅的用户体验。