使用pyinstaller打包程序

1.pyinstaller的下载和安装

一般通过pip命令安装即可,命令如下

pip install pyinstaller

不过,有些程序的打包可能出错,可以安装开发版本,命令如下

pip install https://github.com/pyinstaller/pyinstaller/archive/develop.zip

2.命令参数说明

命令pyinstaller [options] ***.py
可选参数[options]如下:
(1)-F--onefile
将程序打包成一个文件,即exe文件。
优点:比较简洁,毕竟只有一个文件;当程序需要外部资源文件时,打包的资源文件的相对路径将会与打包前工程中的相对路径相同。
缺点:通过这种打包方式打包的exe文件,打开时会花费较长的时间。原因是PyInstaller是将程序所用到的所有外部资源文件,依赖库等压缩到这一个文件中,当运行这一文件时,需要将先前压缩的文件解压到临时文件夹中,耗费较多的时间。
(2)-D--onedir
将程序打包成一个文件夹,其中包括需要的外部资源文件,依赖库,以及exe文件等。PyInstaller默认把程序打包成文件夹。
优点:打开exe文件的速度较快,且可以通过查看文件夹中的dll文件检查缺少哪些依赖库。
缺点:不够简洁,文件夹中包含许多其他文件;外部资源文件的相对路径与打包前在工程中的相对路径有所不同。如果在程序中用到了相对路径访问资源文件,可能会由于找不到指定文件而造成程序运行失败。
(3)--distpath
将打包好的文件或文件夹放置在指定位置,默认为./dist。可以通过--distpath=***修改打包好的文件的放置位置。
(4)--workpath
将打包过程中的临时文件放置在指定位置,默认为./build。可以通过--workpath=***修改临时文件的放置位置。这部分临时文件中有一个warn*.txt文件,其中列举了PyInstaller未能找到的模块,可以通过这个文件检查丢失的依赖库。
(5)--specpath
将生成的spec文件放置在指定位置,默认为和要打包的py文件在同目录下。可以通过--specpath=***修改spec文件的放置位置。
(6)--name-n
指定打包后的exe文件和文件夹名称,默认为和要打包的py文件同名。可以通过--name=***来修改名称。
(7)--icon-i
指定打包后的exe文件的图标,默认为python自带的图标。可以通过--icon=***.ico来修改图标,指定的文件必须是ico文件。
(8)--add-data
添加外部资源文件,可以多次使用。通过--add-data=source;destination添加资源文件,其中source是资源文件(夹)的相对路径,destination是该资源文件(夹)打包在程序中的相对路径,具体例子见实例。
(9)--add-binary
添加二进制文件,可以多次使用。可以用来添加PyInstaller找不到的库文件。
(10)--windowed
适用于GUI程序,即将程序以窗口的形式打包,隐藏控制台。
更多详细的参数介绍可以查看知乎作者王熊貓的文章

3.实例

我使用的是win10操作系统,anaconda环境编写python程序。
编写一个GUI程序,实现修改窗体图标,展示一张图片的功能,test.py代码如下:

# -*- coding: utf-8 -*-

import tkinter as tk  # 导入Tkinter库

window = tk.Tk()  # 创建窗体
window.title('Test')  # 给窗体命名
window.geometry('500x350+500+100')  # 设置窗体大小及位置
window.iconbitmap('icon.ico')  # 设置窗体图标

img = tk.PhotoImage(file='images/qulv.gif')

lab = tk.Label(window, image=img)
lab.pack()

window.mainloop()

工程目录如图:
工程目录
(1)打包成一个文件(即使用--onefile
当不需要外部资源文件时,通过如下命令即可:

pyinstaller --onefile --icon=icon.ico --windowed --name=ShowImage test.py

但是,当程序中需要外部资源文件时,这个命令虽然能够执行,但是运行exe文件时,会出现下图中的问题(我这里截取的是我在其他工程中遇到的相同问题,截图中的Main在上述实例中应该为test):
无法执行脚本***
出现这种情况的具体原因可能是程序找不到指定的外部资源文件或者是未找到程序中引用的依赖库等。
下面只讲将外部资源文件打包入程序中的过程:

  • 如果将程序打包成一个文件,且程序中用到了相对路径访问外部文件,建议在程序中创建一个资源路径函数resource_path(relative_path),代码如下:
# 资源路径函数
def resource_path(relative_path):
    try:
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath('.')
        
    return os.path.join(base_path, relative_path)

然后在使用相对路径时,使用该函数对相对路径进行处理。例如:

img = tk.PhotoImage(file='images/qulv.gif')

应该改为

img = tk.PhotoImage(file=resource_path('images/qulv.gif'))
  • 运行cmd进入test.py所在目录,通过参数--add-data来添加外部资源文件,命令如下:
pyinstaller --onefile --icon=icon.ico --windowed --name=ShowImage --add-data=images/qulv.gif;images/qulv.gif --add-data=icon.ico;. test.py

等待命令执行结束,在同目录下多出来了builddist文件夹,以及ShowImage.spec文件。打开dist文件夹,即可得到打包后的exe程序,图标为icon.ico,名称为ShowImage
如果觉得上面的命令太长,也可以先生成spec文件,通过修改spec文件相关参数添加外部资源文件,步骤如下:

  • 先通过如下命令生成spec文件。注意:设置程序图标,修改名称,设置是否隐藏控制台等需要在下面的命令中设置,否则通过spec文件打包程序时,只有--upx-dir --distpath --nonconfirm --ascii参数可用。当然,也可以修改spec文件设置。
pyi-makespec --onefile --icon=icon.ico --windowed --name=ShowImage test.py

命令执行完毕后,同目录下出现了ShowImage.spec文件。

  • 使用notepad++或记事本打开spec文件,对Analysis()函数参数中的datas进行修改。初始时datas如下所示:
datas=[]

修改为

datas=[('images','images'),('icon.ico','.')]

意思是,将images文件夹打包入程序根目录中,名称为images,将icon.ico文件打包入程序根目录中。

  • 最后,执行如下命令:
pyinstaller ShowImage.spec

等待命令执行完毕,即可得到builddist文件夹,打包的exe文件在dist文件夹中。
(2)打包成文件夹(即没有--onefile参数)
如果将程序打包成文件夹,当程序中使用了相对路径访问外部资源文件,可以不用像打包成单个文件那样,需要在程序中添加一个资源路径函数resource_path(relative_path),直接使用命令,将资源文件放入文件夹中的指定位置。
以上面的程序为例,首先执行命令生成spec文件:

pyi-makespec --windowed --icon=icon.ico --name=ShowImage test.py

然后修改spec文件中的datas,和上面修改spec文件的过程一样。最后执行如下命令:

pyinstaller ShowImage.spec

即可生成buliddist文件夹。在dist文件夹中有ShowImage文件夹,即是打包后的文件夹,该文件夹中包括ShowImage.exe文件,通过运行该文件执行程序。
注意:有时该exe文件的图标可能没有更改,可以将打包后的文件夹复制到其他目录下,该图标可能会改变为指定图标。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值