やりたいこと
・ソフトウェアを起動させるときに画像を表示させたい。
・画像を表示させるときは、ウィンドウの枠を表示させたくない。
・画像を表示させるときは、画像の背景は透明にしたい。
・起動時に画像を表示させ、裏でアプリ本体をロードさせ、その後に起動時の画像を消したい。
動作環境
Windows10
PyCharm
python3
それをスプラッシュスクリーンといいます
スプラッシュスクリーンとは、ソフトウェアを起動させるときに表示される画像のことを言います。
困ったところ
・tkinterで作ったウィジェットのmainloopが抜けられなくて困りました。結局、destroy()ではなくて quit()を使えば上手く行きました。
コード
スプラッシュスクリーンで文字を表示させる場合の例です。
import tkinter
import win32api
import win32con
import pywintypes
label = tkinter.Label(text='Powered by \nHogeHoge株式会社', font=('メイリオ','40'), fg='snow', bg='white')
label.master.overrideredirect(True)
window_width = 700
window_height = 500
label.master.geometry(str(window_width) + "x" + str(window_height) + "+400+300")
label.master.lift()
label.master.wm_attributes("-topmost", True)
label.master.wm_attributes("-disabled", True)
label.master.wm_attributes("-transparentcolor", "white")
hWindow = pywintypes.HANDLE(int(label.master.frame(), 16))
exStyle = win32con.WS_EX_COMPOSITED | win32con.WS_EX_LAYERED | win32con.WS_EX_NOACTIVATE | win32con.WS_EX_TOPMOST | win32con.WS_EX_TRANSPARENT
win32api.SetWindowLong(hWindow, win32con.GWL_EXSTYLE, exStyle)
def call_back_func():
print("call_back_funcの実行")
label.quit()
# label.destroy()
# =============================
# 色々と実験しましたが、結局 quit() すれば、mainloopを抜けることができることを発見しました。
# destroyではmainloopを抜けられないので、注意されたし。
# ==============================
label.pack()
# label.after(3000, call_back_func)
# label.after(3000, lambda: label.quit())
label.after(3000, lambda: [print("call_back_funcの実行"), label.quit()])
label.mainloop()
print("quitを実行すれば、mainloopを抜けることができた。\nめでたし、めでたし。")
print("mainloopを抜けた後に、目的のアプリを表示させれば、自分の考えた通りの動作になります。")
実行結果
よっしゃ! 3秒後にmainloopを抜けることも成功!コード内の説明
Widgetのafter関数
after関数はコールバック関数です。
http://effbot.org/tkinterbook/widget.htm#Tkinter.Widget.after-method
コールバックということはlambda関数を使うチャンスです。
課題
・画面の真ん中に表示出来るようにするのを忘れてました。
・クラス化。
新たな問題発生
・spash screenは表示させて消すことは出来るのですが、その後に立ち上がる本体アプリが一部黒く表示されるというバグを確認しました。解決でき次第、修正コードを追加します。SetWindowPosで再度表示すれば解決する気がしますが、なんかうまくいきませんねぇ・・・。
画像を表示させる場合のコード
後日追加します。