tkinter の アイコン をバイナリ(exeファイル)に埋め込む方法(だいたい コピペ でできる)
tkinterのデフォルトのアイコンは羽のようなアイコンですよね。
これを自分で変更することができます。
これ自体はroot.iconbitmapに指定すればいいだけなのですが、pyinstallerなどでexe化したときに、アイコンファイル(.ico)も同じディレクトリにおいておかないとエラーがでてしまいます。
これを回避するためにexeの中にアイコンファイルを埋め込んでしまって、exe単体で動かせるようにしよう!というのこの記事の趣旨です。
ポイントを最初に挙げておくと、以下の2点が重要です。
1、ソースコード内で使用するアイコンのパスをsys._MEIPASS(※1)を通して取得する。
2、pyinstallerコマンドの時に「--add-data」を使用し、アイコンファイル(.ico)を埋め込む
※1 exe起動時に一時的に展開される場所を取得するためのメソッド
この二点ができていれば、簡単にアイコンをバイナリに埋め込むことができます。
他のサイトなどでは「specファイルをいじる必要が…」とか書かれていますが、「--add-data」オプションを使用すれば必要ありません。
以下に例を示します。単純化のためウィンドを表示させているだけのプログラムです。
アイコンファイル(今回はtest_icon.ico)はソースファイルと同じディレクトリに置いています。
import tkinter
import sys
import os
def temp_path(relative_path):
try:
#Retrieve Temp Path
base_path = sys._MEIPASS
except Exception:
#Retrieve Current Path Then Error
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
logo=temp_path('test_icon.ico')
root=tkinter.Tk()
root.geometry('300x300')
root.title('test')
root.iconbitmap(default=logo)
root.mainloop()
root.quit()
temp_path関数でsys._MEIPASSをとおして、アイコンのパスを取得しています。
使い方は
logo=temp_path([アイコンファイル名])
で、戻り値のアイコンファイルのパスがlogo変数にはいります。
temp_path関数についてはコピペで使用できます。
そして、iconbitmapに取得したパス、つまりlogo変数を渡します。
あとはpyinstallerでバイナリ化(exe化)するだけです。
コマンドは
pyinstaller test.py --onefile --noconsole --icon=test_icon.ico --add-data "test_icon.ico;./"
コマンドの実行場所はソースコードとアイコンファイルのあるディレクトリ(フォルダ)です。
test.pyはソースコード、test_icon.icoはアイコンファイル名です。
アイコンファイルの作成方法については以下の記事を参考にしてください。