ModuleNotFoundError:当 pyinstaller 创建的 EXE 运行 plyer.filechooser.open_file() 和 choose_dir() 时,没有名为“ply
Posted
技术标签:
【中文标题】ModuleNotFoundError:当 pyinstaller 创建的 EXE 运行 plyer.filechooser.open_file() 和 choose_dir() 时,没有名为“plyer.platforms”的模块【英文标题】:ModuleNotFoundError: No module named 'plyer.platforms' when EXE created by pyinstaller runs plyer.filechooser.open_file() and choose_dir() 【发布时间】:2021-03-05 23:25:24 【问题描述】:我的带有 kivy GUI 的 python 脚本在 Pycharm 或 Spyder IDE 中运行流畅。使用 pyinstaller 创建 EXE (Windows) 后,EXE 可以在 GUI 出现的情况下运行,没有任何问题。但是,当我单击运行 plyer.filechooser.open_file()
或 plyer.filechooser.choose_dir()
的按钮时,会出现此错误:
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...
我刚刚意识到 pyinstaller 在“dist”目录下创建的输出目录包含我脚本中使用的包,例如 pandas、numpy、pyexcelerate 等,但不包含 plyer。这很奇怪,因为我的脚本开头有明确的import plyer
。
我的 pyinstaller 规范文件如下所示。我使用 plyer 选择文件的原因是它的体积小,而 PyQt5 会创建巨大的 EXE 大小,而 kivy FileChooser 不会显示用户计算机中可用的所有硬盘驱动器(如果有人知道解决方案会很棒)。
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')
【问题讨论】:
【参考方案1】:将以下隐藏导入添加到规范文件
a = Analysis(
...
hiddenimports=['plyer.platforms.win.filechooser'],
...
【讨论】:
【参考方案2】:我也遇到了同样的问题。
我的解决方法是在使用 pyinstaller 创建 exe 时添加以下参数
--hidden-import plyer.platforms.win.notification
【讨论】:
【参考方案3】:问题是由于缺少隐藏的导入而引起的。尝试像brsaylor 在Windows notification - NotImplementedError: No usable implementation found! #485 中那样包含“特定于平台的模块”:
https://github.com/kivy/plyer/issues/485#issuecomment-457880444
我在 macos 上遇到了与 FileChooser 类似的问题,我通过将特定于平台的模块添加到规范文件中的
hiddenimports
来解决它。对于这个问题,更改将类似于:a = Analysis( ... hiddenimports=['plyer.platforms.win.notification'], ...
【讨论】:
以上是关于ModuleNotFoundError:当 pyinstaller 创建的 EXE 运行 plyer.filechooser.open_file() 和 choose_dir() 时,没有名为“ply的主要内容,如果未能解决你的问题,请参考以下文章
ModuleNotFoundError:当 pyinstaller 创建的 EXE 运行 plyer.filechooser.open_file() 和 choose_dir() 时,没有名为“ply
Pyinstaller“无法执行脚本pyi_rth_pkgres”和缺少包
为啥在 python 控制台中会发生“ModuleNotFoundError”?