起動時にアプリケーションがリモートクラウドストレージからデータベースをロードしている間に表示されるスプラッシュ画面を実装しました。 .update()を呼び出すとスプラッシュ画面が生きています(進行状況バーがあります)。また、別の読み込みプロセスが終了すると破棄されます。その後、メインループが開始され、アプリケーションは正常に実行されます。メインループ外のTkinterスプラッシュ画面とマルチプロセッシング
以下のコードは、私の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)
をoutcomment場合
スプラッシュ画面が正しく表示されます。しかし、私は窓の飾りが必要ではなく、スクリプトの終わりにはまだ画面上にとどまっています。しかし、それは内部的に破壊されており、self.splash
(例えば、.winfo_...
-methods)のメソッド呼び出しは_tkinter.TclError: bad window path name ".!splashscreen"
になります。
また、このコードはwindowsおよびtcl/tk 8.6でも正常に動作します。これはMacのtcl/tk 8.5.18のウィンドウ管理に関するバグ/問題ですか?
あなたのコードは私の目的のとおりに動作します。私は2017-03-21でリリースされたPython 3.6.1を使用しています。 –
あなたはtkinterで 'sleep()'を使ってはいけません。代わりに 'after()'を使用してください –
@SierraMountainTechありがとうございます、私は現在Python 3.6.0で更新を試みます。 after()/ sleep():私はこれを認識しています。これは、シミュレーション目的のために、別個のプロセスでのみ使用されていました。 – Sam