【Python基础002】Pyinstaller打包python程序,轻松搞定程序内有图片导致exe无法运行问题

这里写目录标题

  • 一、简介
    • 1、安装命令
    • 注意:
  • 二、基本使用
    • 1、使用示例
    • 2、常用的命令选项
  • 三、使用spec文件打包
    • 1、生成spec文件
  • 四、常见问题
  • 五、总结

一、简介

Pyinstaller用于window、macOS、Linux系统下将python程序打包为独立可执行的程序文件,用于未安装python的平台上执行python编写的应用程序

1、安装命令

可使用pip命令直接安装Pyinstaller

安装:pip install Pyinstaller

更新:pip install --upgrade pyinstaller

注意:

1、Pyinstaller库会自动将Pyinstaller命令安装到Python解释器目录中,与pip 或pip3命令路径相同,因此可以直接使用。

2、windows上运行Pyinstaller还需要PyWin32或者pypiwin32,其中pypiwin32会在安装Pyinstaller时自动安装。一般安装Pyinstaller完后,其他依赖库就顺带安装了,不需要额外安装。

二、基本使用

1、使用示例

语法:pyinstaller 命令 python源文件路径(需要加.py后缀)

不管需要打包的python程序是单文件应用还是多文件应用,只要在使用pyinstaller命令时编译作为程序入口的Python程序即可(主程序)。

如使用 win+R 命令输入cmd打开终端命令窗口

切换到安装Pyinstaller的环境中,运行Pyinstaller

输入: Pyinstaller -F -w -i logo.ico D:\Develop\mian.py 回车运行

安装成功后在最后一行出现 XXX completed successfully,则说明安装成功, 倒数第二行则是文件保存的位置

打包成功后,会生成三个文件夹(build、config、dist)+一个.spec文件,应用程序在dist文件夹中,可以直接将其移动到另外几个文件的同级目录下,就可以直接运行程序了。如果没有其他需要作为输入的图片、文件等,也可以只保留dist里面的exe文件,其他文件都可以删掉。

2、常用的命令选项

【Python基础002】Pyinstaller打包python程序,轻松搞定程序内有图片导致exe无法运行问题_第1张图片

以上均为Pyinstaller常用命令,其他命令可使用Pyinstaller -h查看

三、使用spec文件打包

使用spec文件打包exe应用程序方法一般用于有多个相关联python程序打包。

因此,第一步我们需要先生成一个spec文件(这个文件也可以自己编写,但是没必要,直接用命令生成后再进行修改即可)

1、生成spec文件

pyi-makespec XXX.py # 运行 pyinstaller,XXX.py为主程序,生成一个spec文件

运行成功后,会在运行路径目录下生成一个XXX.spec文件,打开内容为:

#-- mode: python ; coding: utf-8 –
block_cipher = None # 设置加密,需要安装tinyaes第三方库, 最多16位字符,此处在使用 --key= 会有变化
a = Analysis(
[‘D:\DataAnalysisTool.py’], # 运行的所有py文件,包括所有依赖的py文件,
pathex=[], # 搜索导入的路径列表(此列表为项目绝对路径), 包括选项给出的路径–paths, 项目需要从什么地方导入自定义库
binaries=[], # 脚本需要的非python模块,包括–add-binary选项给出的名称,二进制数据
datas=[], # 应用程序中包含的非二进制文件,包括–add-data选项给出的名称,项目需要用到什么数据,比如图片,视频等。里面格式为tuple,第一个参数是文件路径,第二个是打包后所在的路径,其为一个元组:(‘image/*.png’,‘data/image’)
hiddenimports=[], # 假如打包后打开exe显示module not found,就要把该库添加到hiddenimports里面了
hookspath=[],
hooksconfig={}, # 挂钩配置选项有一个字典组成
runtime_hooks=[],
excludes=[], # 假如你用的python有很多库,但是你不需要用到某个,那么就把它添加到里面, 可以压缩文件大小
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts, # 打包成EXE的脚本文件
# a.binaries, # 如果是单文件模式,则需要添加,多文件也可以添加
# a.zipfiles,
# a.datas,
[],
exclude_binaries=True, # 是否排除二进制文件,为True时,为排除二进制的文件,当文件较大时包含二进制文件运行较快,如果是单文件,则没有这个选项
name=‘DataAnalysisTool’, # 打包程序的名字
debug=False, # 是否启用调试功能
bootloader_ignore_signals=False,
# runtime_tmpdir=None, # 生成单文件时需要这个参数,定义运行时的临时文件夹
strip=False,
upx=True, # 打包的时候进行压缩,FALSE表示不压缩,要用到一个压缩程序UPX, 用于压缩文件,需要单独下载
console=True, # 打包后的可执行文件双击运行时屏幕会出现一个cmd窗口,不影响原程序运行,等于是是否加-w参数
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,

“““添加选项,初始化时没有的”””
icon=“”, # 指定应用程序的图标,传入路径,可以为相对路劲
)
coll = COLLECT(
“”"
如果是单文件模式,不需要这个COLLECT类,同时需要将:
a.binaries,
a.zipfiles,
a.datas,
这些数据文件添加到EXE中
“”"
exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name=‘DataAnalysisTool’,
)

一般使用spec文件打包多py脚本程序时,修改Analysis中前四项即可

修改好spec文件后,在终端命令窗口下输入 Pyinstaller -F -w XXX.spec 即可

四、常见问题

问题1:程序中导入了图片,打包后在自己电脑能正常打开,但是应用程序发给别人就会报错。

方法1:这个问题最简单的解决方法是:图片路径在程序中使用的相对路径,然后在打包完程序后,将图片按照原来的路径放到生成的程序文件夹中,这样就可以轻松解决以上问题。

但若误删了图片,也会导致程序无法使用,于是推荐方法2连同图片一起打包:

方法2

第一步,使用base64编码方式对程序中所使用的图片进行编码操作

import base64


def pic2py(picture_names: list, py_name):
    write_data = []
    for picture_name in picture_names:
        filename = picture_name.replace('.', '_')
        with open("%s" % picture_name, 'rb') as r:
            b64str = base64.b64encode(r.read())
        # 注意这边 b64str 一定要加上.decode()
        write_data.append('%s = "%s"\n' % (filename, b64str.decode()))

    with open(f'{py_name}.py', 'w+') as w:
        for data in write_data:
            w.write(data)
            
            
# 需要转码的图片:
pics = ["./logo.ico"]
# 将pics里面的图片写到 image.py 中
pic2py(pics, 'image')

以上程序会生成一个image.py的python脚本,里面包含了经过base64转码的图片编码

第二步:在主程序中,导入image.py脚本,将图片编码在转成图片即可。

import os
import base64

# 导入图片转码后所在的py文件
from image import *
# 创建临时图片

with open(r'./logo.ico', 'wb') as tmp:  # 创建临时的文件
    # 图片解码,写入文件中去
    tmp.write(base64.b64decode(logo_ico))    # logo_ico为转码的图片名字

# 在主程序开始前调用上面程序,会在open的路径处生成这张图片,后面的程序就可以调用相关的图片

	# 在主程序运行结束时删掉生成的图片
    os.remove(r'./logo.ico')

问题2:使用Pyinstaller打包程序成功后,运行程序报 无法找到相对的库 文件。

方法:直接将Pyinstaller安装到需要打包的程序文件环境下就ok

五、总结

(1)一般打包程序所依赖的文件不多的话,可以直接用Pyinstaller命令打包,不需要用spec文件打包(亲测,有两个关联脚本,一样可以直接对主程序打包)。

(2)打包一般使用-F -w -n -i 命令就足够了

(3)如果想指定打包生成文件的目录,可以切换到指定目录路径下使用Pyinstaller命令(前提是用conda 切换到Pyinstaller的安装环境)

你可能感兴趣的:(Python基础,python,linux,开发语言)