Если другие люди воспроизводят это, и кто-то намекает мне, где сообщить об этом как об ошибке, я с радостью это сделаю.
лизовал заставку, которая отображается, когда мое приложение загружает базу данных из удаленного облачного хранилища при запуске. Заставка поддерживается (есть индикатор выполнения) с вызовами .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_...
-методы) приводят к_tkinter.TclError: bad window path name ".!splashscreen"
.
Кроме того, этот код прекрасно работает под Windows и Tcl / TK 8,6. Это ошибка / проблема с управлением окнами tcl / tk 8.5.18 на Mac?