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的主要内容,如果未能解决你的问题,请参考以下文章

Python3中.pyi文件介绍

ModuleNotFoundError:当 pyinstaller 创建的 EXE 运行 plyer.filechooser.open_file() 和 choose_dir() 时,没有名为“ply

Pyinstaller“无法执行脚本pyi_rth_pkgres”和缺少包

为啥在 python 控制台中会发生“ModuleNotFoundError”?

ModuleNotFoundError 没有名为 onetimepad 的模块?

Python - 安装新包时出现 ModuleNotFoundError