PyQt5 exe化時の自作アイコンの埋込み方法(windows10)

Python

PyQt5でプログラムをしてPyInstallerでexe化すると、アイコンがPythonロゴになってしまいますが、このロゴを自作アイコンに変える方法を記載します。

最初は、ネット上の先輩方の記事を見てすぐ出来るものと思っていましたが、exeファイルへのicoファイル埋め込みがどうしても出来なくて放置していました。

先日、ネット語学レコーダのソフト作成を機に、断片的な情報をつなぎ合わせることで、ようやく自作アイコンへ変更することが出来ましたので作業手順を記事にします。

iconファイルを作る

Windowsアイコンのファイル形式はICOとなっており、jpegやpng形式が使えます。画像の最大サイズはICO形式で128x128ピクセルとなっています。

ICOファイルは普通のビットマップファイルの拡張子が.icoになっただけですので、Windowsペイントでも作ることも出来ますが、画像の圧縮とサイズ合わせが作業が難儀するため、以下のサイトでコンバートを行うのが早くて確実です。(自作アイコンはペイントなどで事前に作ってくださいね)

JPEG/PNG/GIFからアイコンを作成する「アイコン コンバータ」
このWebアプリケーションは、ブラウザ上でJPEG/PNG/GIFからWindowsやMac、Android、iPad、iPhoneなどのfaviconとして利用されるアイコン(.ICO形式、.PNG形式)ファイルへ変換するものです。

サイトで変換が終わったら、「右クリック」→「名前をつけて保存」で、.icoファイルに保存します。ICOファイルの作成はとても簡単です。

実行ウィンドウのアイコンの埋め込み

Pyqt5で実行しているウィンドウに自作アイコンを表示させるには、PyQt5のsetWindowIcon(QIcon(file_name))の1行コードを追加すれば表示できます。

def main():
    app = QApplication(sys.argv)
    app.setWindowIcon(QIcon(ico_path('falcon.ico'))) →この行を入れる
    main_window = Radiru_rec()
    main_window.show()
    sys.exit(app.exec_())

しかし、このコードだけではプログラム起動の度にicoファイルを読み込む必要があります。exe化した場合においても、icoファイルを個別に添付する必要があり利便性が損なわれます。

そこでicoファイルをexeファイルに埋め込む作業を追加します。

exeファイルにico画像を組み込む

exeファイルにico画像を埋め込むには、PyInstallerで--add-dataオプションで処理が出来ます。サンプルのコマンドは以下の通り。

> python -m PyInstaller icon_test.py --onefile --noconsole --icon=falcon.ico --add-data "falcon.ico;./"

しかし、このままではexeファイルに埋め込んだicoファイルを呼び出す仕組みをいれていないため、まだexeファイル単体では自作アイコンが反映されません。処置はもうひと手間必要です。

pyファイルにicoファイルを呼び出すコードを追加

PyInstallerでパッケージングされたファイルはメモリ上に一時展開されますので、一時展開されたicoファイルを呼び出す仕組みを入れる必要があります

exeに内包されて一時展開されているファイルのパスは、sys._MEIPASSで取得することが出来ますので、以下の関数(ico_path)を付加します。

サンプルコードの動作は次のとおりです。

  • exeで実行したとき:exeファイル内のicoファイルを読み込む
  • exe以外で実行したとき:同フォルダにあるicoファイルを読み込む
import sys
# QIcon設定
def ico_path(relative_path):
    try:
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath(".")
    return os.path.join(base_path, relative_path)

# mainウィンドウ呼び出し
def main():
    app = QApplication(sys.argv)
    app.setWindowIcon(QIcon(ico_path('falcon.ico')))
    main_window = Radiru_rec()
    main_window.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

コマンドプロンプトで動作することが確かめられたら、再度PyInstallerでexe化し、icoファイルの存在しないフォルダ(通常はdistフォルダ)で単体動作させます。

プログラムが起動して、タスクバーにアイコンが表示されることが確認できたら、アイコンの埋込が完了です。

自作ソフトでアイコンがカスタマイズできると市販ソフトのように見えて感動ものです。PyQt5でGUIプログラムをされる場合は、是非お試しください。