Pyinstaller的安装及简单使用

 

(1)安装:

用传统的pip install pyinstaller出错,在https://pypi.org/project/PyInstaller/#files上下载PyInstaller-3.4.tar.gz (3.5 MB),解压,cmd设置当前路径未,解压到的文件夹位置,dos上输入 python setup.py install

当-d all时候,打开生成的可执行文件,会输出各种信息,比如调用的包有哪些,分别来自哪里(imports 选项)

  • all: All three of the following options.
  • imports: specify the -v option to the underlying Python interpreter, causing it to print a message each time a module is initialized, showing the place (filename or built-in module) from which it is loaded. See https://docs.python.org/3/using/cmdline.html#id4.
  • bootloader: tell the bootloader to issue progress messages while initializing and starting the bundled app. Used to diagnose problems with missing imports.
  • noarchive: instead of storing all frozen Python source files as an archive inside the resulting executable, store them as files in the resulting output directory

(2)使用注意事项:

(a)如果在源码中用相对路径调用图片文件或者图标文件,打包时会出现如下图的错误:

解决方法很简单,只需要在源码中,相对路径改为绝对路径,然后在打包时,再将绝对路径传入pyinstaller 命令即可。

举例说明,具体为:

(b)使用图片:

在源码中,使用绝对路径:

img1=PhotoImage(file=r'F:\FIELS\tkinGui\Example_pyinstaller\1.gif')
Button(win,image=img1).pack()

使用pyinstaller时,首先用cd将dos现在路径改为目标打包py文件的位置,然后 pyinstaller  -w  --add-data="F:\FIELS\tkinGui\Example_pyinstaller\1.gif;image"  imgButton.py

即可。注意,这里--add-data="源地址;目标地址“,源地址为搜索文件的地址,这里使用绝对路径,";"为os.pathsep(平台路径分割符,window为;其他为:),目标地址必须填写image,是代码运行时候所在文件夹下的文件名“image”,详见https://pyinstaller.readthedocs.io/en/stable/usage.html

(c)使用图标:

在源码中,使用绝对路径:

root=Tk()
root.title('BRN1.0')
root.resizable(0,0)
root.iconbitmap(r'F:\FIELS\tkinGui\BatchReName\BatchReName.ico')

pyinstaller 命令: pyinstaller -w -i="F:\FIELS\tkinGui\BatchReName\BatchReName.ico"  BatchReName.py

(3)

打包后,代码中的ico,及image搜索路径将依赖于.py文件中设定的路径,为了保证打包形成exe文件后,仍能找到用户电脑中的路径,.py文件中的路径最好设置成相对路径,再结合os.path.abspath形成用户电脑上的绝对路径。如:

 

ImagePath=r'.\image\BatchReName.ico'
def resource_path(relative_path):
	"""
	return absolute path
	"""
	if hasattr(sys,'_MEIPASS'):
		base_path=sys._MEIPASS
	else:
		base_path=os.path.abspath('.')
	return os.path.join(base_path,relative_path)
ImagePath=resource_path(ImagePath)

 

  将imagepath从相对路径转化为用户电脑上的绝对路径。

(4)打包脚本后运行,提示vcruntime140.dll 未在指定的window上运行,

找了下,说是版本不同,或者upx压缩错误,然后就加了下 --noupx命令,打包完,软件大了一圈,不过再运行就没报错了。UPX一个免费的对各个操作系统可执行文件进行压缩的可执行打包器(https://upx.github.io/),PyInstaller looks for UPX on the execution path or the path specified with the --upx-dir option. If UPX exists, PyInstaller applies it to the final executable, unless the --noupx option was given. UPX has been used with PyInstaller output often, usually with no problems.

 

具体原因应该是安装的ups是64位的,然后压缩了32位的,导致报错了

参考文章链接:https://blog.csdn.net/jpch89/article/details/81183019

(5)

打包时会出现问题Cannot find existing PyQt5 plugin directories,解决方法就是用everything搜索PyQt5,找到 /Library/plugins路径下的PyQt5文件夹,将里面的dll动态库pyqt5qmlplugin.dll复制出来按照错误提示的路径,一个个的新建文件夹,形成目录C:\qt5b\qt_1524647842210_h_env\Library\plugins,将刚才复制出来的dll动态库拷贝进去即可。亲测有效。
————————————————
原文链接:https://blog.csdn.net/lixiaoyu101/article/details/84620336

(6)

PyQt5打包后,自己电脑上运行可以,但拷贝到相同系统的其他电脑上,not find Qt platform plugin “windows”,全网找了半天,最后通过,将platform文件夹下的所有dll文件拷贝到跟exe文件一个目录下,成功运行。感谢博文https://blog.csdn.net/okfu_DL/article/details/84566545给我的灵感,不过跟它的方法不太一样,它是将整个platform文件夹拷贝到跟exe一个目录的,我试了下没成功。platform文件在python文件下,如E:\software\py\Lib\site-packages\PyQt5\Qt\plugins\platforms,注意这个platform应该是负责打包的解释器下的platform文件。

当本机解释器抛出not find platform警示框后,在环境变量中添加QT_QPA_PLATFORM_PLUGIN_PATH变量,值为,比如我的是C:\Users\AppData\Local\Programs\Python\Python36\Lib\site-packages\PyQt5\Qt\plugins

(7)打包成功后,运行.exe报错: ModuleNotFoundError: No module named ’numpy.core.__dtype_ctypes’

 

直接运行软件会闪退,可以通过PowerShell(Windows)来运行查看错误,与此类似的还有ModuleNotFoundError: No module named ’sklearn.neighbors.typedefs’,解决方案类似。
总结一下: 这些问题主要从GitHub上该项目的issue模块得到了解决方案(我们不是孤独的,大家都遇到了同样的问题)
可以通过两种方式得到解决:

 

第一种是hooks(这也是作者推荐的方式),这是一种更优雅但是却不是最方便的方式,如标题的错误我是这种方式解决的:
将下述代码放到hook-numpy.core.py文件里(当然你需要把这个路径在命令行或者.spec中告诉pyinstaller)。

 

hiddenimports=['numpy.core._dtype_ctypes']

 

更多的我采用的是第二种方法:直接在hiddenimports中指定(也可在命令行参数中指定,如下图)。
pyinstaller -F --hidden-import=numpy.core._dtype_ctypes --noupx kmlCoordExtractor.py
--hidden-import选项可以叠加,如--hidden-import=sklearn.tree._utils后可以再接着--hidden-import=sklearn.neighbors.quad_tree。
 
这个hidden-import 一定要填写全,漏掉一个都不行,比如pycomcad(本人自制小库),有时候就需要填写'pythoncom','win32com'。另外程序运行中,不能打包,这种情况也时有发生而自己一时半会也没意识到。
参考博文:https://blog.csdn.net/alwaysyxl/article/details/86703647
 
推荐一个大神写的关于pyinstaller博客:https://blog.csdn.net/weixin_42052836/article/details/82315118
 

(8)  pyinstaller打包报错: RecursionError: maximum recursion depth exceeded:

某个库自己递归遍历超过了python的栈高度限制,在xxx.spec文件中增加两行(添加在原文件第二行):
import sys
sys.setrecursionlimit(5000)

 然后,pyinstaller xxx.spec就可以了

 (9)昨晚突然想到一个方法,对于闪退的情况,想不退出,查明exception在哪儿。可以整体try except ,然后input 阻断退出。考虑到测试打包的文件可能非常的大,所以用另一个程序调用测试打包的文件,但要注意的是先import,再os执行测试文件,因为很多打包情况是hidden-import的包没有找到引起的,所以如果是这种情况,可能导入这关都过不了。

 

 

 达到了既定效果!

(10)

pyinstaller 打包的时候报错:

Fatal error: PyInstaller does not include a pre-compiled bootloader for your
platform. For more details and instructions how to build the bootloader see

这个问题主要是后台的win10防火墙把虚拟环境中的pyinstaller的pyinstaller\PyInstaller\bootloader\Windows-32bit中的runw.exe删掉了,可以通过原有python库中已有的库中去复制粘贴到相应的路径下,防火墙应该时删掉了某些重要的东西。

 

posted @ 2019-05-15 13:16  JohnYang819  阅读(9461)  评论(0编辑  收藏  举报