Python
Kivy
PyInstaller

KivyアプリをPyinstallerでEXE化する


はじめに

Kivyで実装したGUIアプリをEXE化し配布する機会があったためまとめます。

基本的に公式に従えばいけますが、アプリでfilechooserを使っていると依存を追記する必要があります。

以下、環境


  • OS: Windows 10 Pro

  • Python 3.6.6

  • Pythin: 3.5.6

  • Kivy: 1.10.1

  • Pyinstaller: 3.4


結論

以下の順番でEXE化します。


  1. PythonスクリプトをPyinstallerでEXE化

  2. SPECファイルに依存ファイルを記述

  3. SPECファイルを使ってPyinstallerでEXE化

filechooserを使っている場合は、

SPECファイルのhiddenimports['win32file', 'win32timezone']を追記。


詳細

GUIアプリが以下のファイルで構成されているとします。

また、すべて同一ディレクトリに存在するとします。

main.py (アプリの動作を定義するPythonスクリプト)

app.kv (アプリのレイアウトを定義するKivy Languageファイル)
lang.ttf (フォントデータ)


1. PythonスクリプトをPyinstallerでEXE化

Pyinstallerを普通に用いてEXE化します。

BashなりAnaconda Promptなりで以下を実行。

# --name EXEファイルの名前

# --onefile 依存ファイルを1つのEXEファイルへ統合
# --noconsole EXEを実行したときのコンソール出力を無効
# --clear 前回ファイルを削除
$ pyinstaller --name [EXE_NAME] --onefile --noconsole main.py

ディレクトリdirが作られ、この中にEXEファイルが生成されますが、この段階ではまだ無視です。

(依存ファイルが含まれていないため起動しません)

使うのは、main.pyと同階層に生成される[EXE_NAME].specファイル。


2. SPECファイルに依存ファイルを記述

[EXE_NAME].specを以下のように編集します。

*1: 公式より依存ファイルをインポート

*2: kvファイルとフォントファイルをインポート。ディレクトリが違う場合は指定

*3: アプリでKivyのfilechooserを使っている場合はこれが必要。filechooser内部の依存なので、使っていないときはいらない

*4: FalseでEXE実行時にコンソール非表示

$ vim [EXE_NAME].spec

# -*- mode: python -*-
from kivy.deps import sdl2, glew # 追記(*1)
block_cipher = None

a = Analysis(['main.py'],
pathex=['C://Users/USER/project'],
binaries=[],
datas=[('app.kv', '.'), ('lang.ttf', '.')], # 追記(*2)
hiddenimports=['win32file', 'win32timezone'], # 追記(*3)
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
*[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)], # 追記(*1)
name='TEST',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
runtime_tmpdir=None,
console=False ) # 編集(*4)

編集が終わったら保存します。


3. SPECファイルを使ってPyinstallerでEXE化

SPECファイルを指定して、EXE化しなおします。

$ pyinstaller [EXE_NAME].spec

いじょーで完了です。