My python script with kivy GUI runs smoothly in Pycharm or Spyder IDE. After creating the EXE (Windows) using pyinstaller, the EXE can run with the GUI appearing without any issues. However when I click buttons that run plyer.filechooser.open_file() or plyer.filechooser.choose_dir(), this error appears:
Traceback (most recent call last):
File "plyer\utils.py", line 96, in _ensure_obj
ModuleNotFoundError: No module named 'plyer.platforms'
[INFO ] [Base ] Leaving application in progress...
I just realized that the output directory created by pyinstaller under "dist" directory contains the used packages in my script such as pandas, numpy, pyexcelerate etc. but NOT plyer. That is strange because my script has explicitly import plyer at the beginning.
My spec file for pyinstaller is shown below. The reason I'm using plyer to select files is because of its small size whereas PyQt5 creates huge EXE size while kivy FileChooser does not show all hard drives available in a user's computer (if anyone knows solution for this would be great).
import os
from os.path import join
from kivy import kivy_data_dir
from kivy.deps import sdl2, glew
from kivy.tools.packaging import pyinstaller_hooks as hooks
block_cipher = None
kivy_deps_all = hooks.get_deps_all()
kivy_factory_modules = hooks.get_factory_modules()
# list of data filepath (your *.kv, image files, kivymd files) to copy to the output directory
datas = [('./gui.kv', '.'),
('./venv/Lib/site-packages/kivymd', 'kivymd')
]
# list of modules to exclude from Analysis
excludes_a = ['Tkinter', '_tkinter', 'twisted', 'docutils', 'pygments']
# list of hiddenimports
hiddenimports = kivy_deps_all['hiddenimports'] + kivy_factory_modules
# binary data
sdl2_bin_tocs = [Tree(p) for p in sdl2.dep_bins]
glew_bin_tocs = [Tree(p) for p in glew.dep_bins]
bin_tocs = sdl2_bin_tocs + glew_bin_tocs
# assets
kivy_assets_toc = Tree(kivy_data_dir, prefix=join('kivy_install', 'data'))
# source_assets_toc = Tree("images", prefix="images")
# assets_toc = [kivy_assets_toc, source_assets_toc]
assets_toc = [kivy_assets_toc]
tocs = bin_tocs + assets_toc
a = Analysis(['main.py'],
pathex=[os.getcwd()],
binaries=None,
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
runtime_hooks=[],
excludes=excludes_a,
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe1 = EXE(pyz,
a.scripts,
name='main', # name of output *.exe file
exclude_binaries=True,
# icon=join('images', 'mywinapp.ico'),
debug=False,
strip=False,
upx=True,
console=True) # set to console-based, NOT window-based.
coll = COLLECT(exe1,
a.binaries,
a.zipfiles,
a.datas,
*tocs,
strip=False,
upx=True,
name='Parser')