You can use the created python script to create a MacOS application using pyinstaller.
At first I used py2app, but the result file size was different as below. --Py2app result: 35MB --Pyinstaller result: 25MB There is no reason not to use Pyinstaller. Installation is now possible with PIP. (I couldn't do it last year)
pip install pyinstaller
That's it
It is recommended to drive the pyinstaller through * .spec files.
The basic structure of the spec file is as follows.
# -*- mode: python -*-
# filename = Main.spec
a = Analysis(['Main.py'],
pathex=['/Users/.../ProgramNameDir'],
hiddenimports=[],
hookspath=None,
runtime_hooks=None)
pyz = PYZ(a.pure)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
name='Main',
debug=False,
strip=None,
upx=True,
console=False , icon='mainIcon.ico')
app = BUNDLE(exe,
name='Main.app',
icon='mainIcon.ico')
In this case, read main.py and create Main.app. icon wears mainIcon.ico.
Main.py exists in "/ Users / ... / ProgramNameDir" and refers to the lib file of "./lib" under it. So, modify it a little so that the * .spec file can recognize "./lib".
# -*- mode: python -*-
# filename = Main.spec
###personal./Code to recognize libs###
import sys
myLibPath = './libs'
sys.path.append(myLibPath)
############################
a = Analysis(['Main.py'],
pathex=['/Users/.../ProgramNameDir'],
hiddenimports=[],
hookspath=None,
runtime_hooks=None)
pyz = PYZ(a.pure)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
name='Main',
debug=False,
strip=None,
upx=True,
console=False , icon='mainIcon.ico')
app = BUNDLE(exe,
name='Main.app',
icon='mainIcon.ico')
There is another problem. Main.py uses the image file in / Users / ... / ProgramNameDir / img. This cannot be read by the final app even if it is added in sys.path.append. This is because the image file handling mechanism is different.
When the application created by pyinstaller is driven, necessary files (image files, etc.) are copied in the temporary folder (temp folder) at the location "_MEIPASS". Therefore, it is necessary to recognize "_MEIPASS" in the * .py code.
Add this function in Main.py.
def resource_path(relative):
if hasattr(sys, "_MEIPASS"):
return os.path.join(sys._MEIPASS, relative)
return os.path.join(relative)
Then convert the image reference child in the code. example:
"./img/Title.png " --> resource_path("./img/Title.png ")
Add Tree () to the * .spec file.
#filename = Main.spec import sys myLibPath = './libs' sys.path.append(myLibPath) a = Analysis(['Main.py'], pathex=['/Users/.../ProgramNameDir'], hiddenimports=[], hookspath=None, runtime_hooks=None) pyz = PYZ(a.pure) exe = EXE(pyz, Tree('img',prefix='img'), #<--Folder name with the image to add a.scripts, a.binaries, a.zipfiles, a.datas, name='Main', debug=False, strip=None, upx=True, console=False , icon='mainIcon.ico') app = BUNDLE(exe, name='Main.app', icon='mainIcon.ico')
I have a MacBook pro. That is, I am using Retina Display. If you make an application made with pyinstaller as it is, the message box and dialog will appear blurred on the Retina Display, so it is ugly.
Add info_plist to BUNDLE to solve it.
#filename = Main.spec import sys myLibPath = './libs' sys.path.append(myLibPath) a = Analysis(['Main.py'], pathex=['/Users/.../ProgramNameDir'], hiddenimports=[], hookspath=None, runtime_hooks=None) pyz = PYZ(a.pure) exe = EXE(pyz, Tree('img',prefix='img'), a.scripts, a.binaries, a.zipfiles, a.datas, name='Main', debug=False, strip=None, upx=True, console=False , icon='mainIcon.ico') app = BUNDLE(exe, name='Main.app', info_plist={ 'NSHighResolutionCapable': 'True'}, #<-- Option for High Resolution icon='mainIcon.ico')
This is about the end.
#### **`pyinstaller Main.spec`**
```spec
You can make an app with.
In the case of py2exe and py2app, there are many cases, but in the case of pyinstaller, there are not so many, so I recorded it for organization.
Recommended Posts