我已经实现了一个启动屏幕,该屏幕在我的应用程序启动时从远程云存储加载数据库时显示.初始屏幕通过调用.update()保持活动状态(上面有进度条),并在单独的加载过程结束后销毁.此后,将启动主循环,并且应用程序将正常运行.
下面的代码曾经在我的Mac上使用python 3.6和tcl / tk 8.5.9正常工作.但是,在更新到Sierra之后,我被迫将tk更新到ActiveTcl 8.5.18.现在,在单独的过程完成之前,不会显示启动画面,但是会出现并与根窗口一起显示并停留在屏幕上(即使调用了.destroy()方法).
import tkinter as tk
import tkinter.ttk as ttk
import multiprocessing
import time
class SplashScreen(tk.Toplevel):
def __init__(self, root):
tk.Toplevel.__init__(self, root)
self.geometry('375x375')
self.overrideredirect(True)
self.columnconfigure(0, weight=1)
self.rowconfigure(0, weight=1)
self.label = ttk.Label(self, text='My Splashscreen', anchor='center')
self.label.grid(column=0, row=0, sticky='nswe')
self.center_splash_screen()
print('initialized splash')
def center_splash_screen(self):
w = self.winfo_screenwidth()
h = self.winfo_screenheight()
x = w / 2 - 375 / 2
y = h / 2 - 375 / 2
self.geometry("%dx%d+%d+%d" % ((375, 375) + (x, y)))
def destroy_splash_screen(self):
self.destroy()
print('destroyed splash')
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.start_up_app()
self.title("MyApp")
self.columnconfigure(0, weight=1)
self.rowconfigure(0, weight=1)
self.application_frame = ttk.Label(self, text='Rest of my app here', anchor='center')
self.application_frame.grid(column=0, row=0, sticky='nswe')
self.mainloop()
def start_up_app(self):
self.show_splash_screen()
# load db in separate process
process_startup = multiprocessing.Process(target=App.startup_process)
process_startup.start()
while process_startup.is_alive():
# print('updating')
self.splash.update()
self.remove_splash_screen()
def show_splash_screen(self):
self.withdraw()
self.splash = SplashScreen(self)
@staticmethod
def startup_process():
# simulate delay while implementation is loading db
time.sleep(5)
def remove_splash_screen(self):
self.splash.destroy_splash_screen()
del self.splash
self.deiconify()
if __name__ == '__main__':
App()
我不明白为什么会这样以及如何解决.有人可以帮忙吗?谢谢!
更新:
如果您忽略了self.overrideredirect(True)行,则初始屏幕会正确显示.但是,我不希望窗口装饰,并且脚本结尾时它仍然保留在屏幕上.不过,它在内部已被销毁,任何其他对self.splash的方法调用(例如.winfo _…- methods)都会导致_tkinter.TclError:错误的窗口路径名“.!splashscreen”.
另外,此代码在Windows和tcl / tk 8.6下也能正常工作.这是Mac上tcl / tk 8.5.18的窗口管理的错误/问题吗?