Python3.4 + matplotlib + numpy + PyQt5のセットでPyInstallerを使ってexeファイルを作る
Pythonで作ったmatplotlib + numpy + PyQt5なGUIアプリをPyInstallerでexe化しようと思ったら3時間溶かしたのでメモ。
実行環境
- Python3.4.5 32bit
- Python3.5.x系だとうまくいかない。
- Windows10 Pro 64bit
- 64bitだけどPythonは32bitで。
numpyとscipyはこのサイトからダウンロード&インストール
http://www.lfd.uci.edu/~gohlke/pythonlibs/www.lfd.uci.edu
ファイルダイアログの読み込みの解決
PyQt5でファイルダイアログ等を使用する場合、tkinterのインポートも必要です。 PyInstallerはimportのあたりを解析してパッケージに含めるものを決めているようです。 インポートは結局こんな感じに。
from PyQt5.QtWidgets import (QMainWindow, QApplication, QWidget, QGridLayout, QVBoxLayout, QHBoxLayout,QFileDialog, QLabel, QLineEdit, QPushButton) from window import Ui_Form from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.backends.backend_qt5 import NavigationToolbar2QT as NavigationToolbar from matplotlib.figure import Figure import matplotlib.pyplot as plt import numpy as np import random import seaborn as sns import copy import tkinter import tkinter.filedialog as FileDialog
hook-numpyを作成する
問題はこのままでは動きません。実行時に次のようなエラーが吐かれます。
Intel MKL FATAL ERROR: Cannot load mkl_intel_thread.dll.
そこで、StackOverflowの神々が書いたhook-numpy.py
というスクリプトをPyInstallerに追加します。
追加先は、C:\[Python34の位置]\Lib\site-packages\PyInstaller\hooks
で、次のようなスクリプトを追加します。
from PyInstaller import log as logging from PyInstaller import compat from os import listdir mkldir = compat.base_prefix + "/Lib/site-packages/numpy/core" logger = logging.getLogger(__name__) logger.info("MKL installed as part of numpy, importing that!") binaries = [(mkldir + "/" + mkl, '') for mkl in listdir(mkldir) if mkl.startswith('mkl_')]
exe化のコマンド
ここまでやって、以下のようなコマンドで実行。
pyinstaller --hidden-import="tkinter" main.py
やっと動いた!寝る!