cx_Freeze で Macアプリを作成する(4)
cx_Freeze の Macアプリ作成に対応したら、py2app に影響してしまった
cx_Freeze でも Macアプリを作成できるよう"QuickIR.py" を修正したところ、今度は py2app でアプリ作成したら動かなくなってしまった。原因はこの修正だ。
def find_image_file(path):
if getattr(sys, 'frozen', False):
# The application is frozen
datadir = os.path.dirname(sys.executable)
else:
# The application is not frozen
# Change this bit to match where you store your data files:
datadir = os.path.dirname(__file__)
return os.path.join(datadir, path)
〜略〜
def createToolbar(self, toolbar):
"""make toolbar"""
self.img_folder_add = PhotoImage(file=find_image_file('images/folder_add.gif'))
self.img_folder_ren = PhotoImage(file=find_image_file('images/folder_rename.gif'))
self.img_folder_del = PhotoImage(file=find_image_file('images/folder_delete.gif'))
self.img_file_add = PhotoImage(file=find_image_file('images/file_add.gif'))
self.img_file_post = PhotoImage(file=find_image_file('images/file_post.gif'))
self.img_file_ren = PhotoImage(file=find_image_file('images/file_rename.gif'))
self.img_file_del = PhotoImage(file=find_image_file('images/file_delete.gif'))
実は py2app で作成した Macアプリでもgetattr(sys, 'frozen', False) はTrueになる(sys.frozen属性が存在する)。そして、sys.executable ファイルは"QuickIR.app/Contents/MacOS/QuickIR" であるため、そのディレクトリパス名は"QuickIR.app/Contents/MacOS" になる。その結果、"QuickIR.app/Contents/MacOS/images" 配下の画像ファイルを読み込もうとするのだが、そこにimages ディレクトリは存在しない。py2app はdata_files で取り込むように指定された物を、"QuickIR.app/Contents/MacOS" ではなく"QuickIR.app/Contents/Resources" に置くからだ。
プログラム以外のファイルはResources に置くという py2appの仕様は至極自然に思える。しかし、このまま py2appで作成した Macアプリが動かないのも困ったものだ。少し考えた末、画像ファイルはResources/images 配下に置いたままにして、MacOS からResources/images へのシンボリックリンクを張ることにしようと思う。
また、py2app のdata_files もファイルだけでなくフォルダを指定する事が可能である事や、アプリに取り込まない除外パッケージをexcludes で指定できる事が分かったので、setupファイルも以下のように修正した。
"""
This is a setup.py script generated by py2applet
Usage:
python setup.py py2app
"""
from setuptools import setup
APP = ['QuickIR.py']
APP_NAME = 'QuickIR'
VERSION = '1.0.9'
DATA_FILES = ['images']
OPTIONS = {
'argv_emulation': False,
'iconfile': 'app.icns',
'includes': ['irkit', 'resolve_irkit', 'pybonjour'],
'excludes': [
'logging', 'distutils',
'multiprocessing', 'pydoc_data',
'test', 'unittest',
'xml', 'xmlrpc'
],
'strip': True,
'plist': {
'CFBundleName': APP_NAME,
'CFBundleDisplayName': APP_NAME,
'CFBundleGetInfoString': "QuickIR IRKit controller " + VERSION,
'CFBundleIdentifier': "jp.ddo.y-naito.QuickIR",
'CFBundleVersion': VERSION,
'CFBundleShortVersionString': VERSION,
'NSHumanReadableCopyright': "Copyright (C) 2015-2016, N@i.jp, All Rights Reserved"
}
}
setup(app=APP,
data_files=DATA_FILES,
options={'py2app': OPTIONS},
setup_requires=['py2app'])
この setupスクリプトを用いて py2appで Macアプリを作成するシェルスクリプト"make_app.sh" は以下のようになる。最後の行がシンボリックリンクを張っている処理だ。
#!/bin/sh
rm -rf build dist
python3 setup.py py2app $@
cd ./dist/QuickIR.app/Contents/MacOS
ln -s ../Resources/images ./images
py2exe の場合も影響が出ていないか確認しないといけないな。今夜はもう時間がないので、検証結果はまた後日に。
|