将Python文件编译为exe可执行程序
- 1. 编写计算器源码
- 2. 安装PyInstaller
- 3. 用 PyInstaller 生成可执行程序
- 4. 设置打包后的版本信息
- 5. 编译.py文件为.exe可执行文件(有版本配置文件)
- 6. 执行.exe文件隐藏cmd窗口
Python程序py格式文件的优点是可以跨平台,但运行必须有Python环境,没有Python环境无法运行py格式文件。有没有方法,用户不同安装Python就可直接运行开发的项目工程?答案是肯定的。这就涉及到需要将Python的.py格式文件编写的脚本编译成一个系统可执行文件,这可用
PyInstaller来实现。
PyInstaller支持在在Windows/Linux/Mac环境下将Python脚本打包成可执行程序,在没有Python环境的机器上运行。注意:需要在哪个操作系统平台一运行,需在相应的操作系统(或虚拟机)下编译。
1. 编写计算器源码
import tkinter as tk root = tk.Tk()root.title('计算器')root.geometry('295x280+100+100')font =('宋体',20)font_16 =('宋体',16)root.attributes("-alpha",0.9)result_num = tk.StringVar()result_num.set('')tk.Label(root,textvariable=result_num,font=font,height=2,width=20,justify=tk.LEFT,anchor=tk.SE).grid(row=1,column=1,columnspan=4)button_clear = tk.Button(root,text='C',width=5,font=font_16,relief=tk.FLAT,bg='#b1b2b2')button_back = tk.Button(root,text='←',width=5,font=font_16,relief=tk.FLAT,bg='#b1b2b2')button_division = tk.Button(root,text='÷',width=5,font=font_16,relief=tk.FLAT,bg='#b1b2b2')button_multiplication = tk.Button(root,text='×',width=5,font=font_16,relief=tk.FLAT,bg='#b1b2b2')button_clear.grid(row=2,column=1,padx=4,pady=2)button_back.grid(row=2,column=2,padx=4,pady=2)button_division.grid(row=2,column=3,padx=4,pady=2)button_multiplication.grid(row=2,column=4,padx=4,pady=2)button_seven = tk.Button(root,text='7',width=5,font=font_16,relief=tk.FLAT,bg='#eacda1')button_eight = tk.Button(root,text='8',width=5,font=font_16,relief=tk.FLAT,bg='#eacda1')button_nine = tk.Button(root,text='9',width=5,font=font_16,relief=tk.FLAT,bg='#eacda1')button_subtraction = tk.Button(root,text='-',width=5,font=font_16,relief=tk.FLAT,bg='#b1b2b2')button_seven.grid(row=3,column=1,padx=4,pady=2)button_eight.grid(row=3,column=2,padx=4,pady=2)button_nine.grid(row=3,column=3,padx=4,pady=2)button_subtraction.grid(row=3,column=4,padx=4,pady=2)button_four = tk.Button(root,text='4',width=5,font=font_16,relief=tk.FLAT,bg='#eacda1')button_five = tk.Button(root,text='5',width=5,font=font_16,relief=tk.FLAT,bg='#eacda1')button_six = tk.Button(root,text='6',width=5,font=font_16,relief=tk.FLAT,bg='#eacda1')button_addition = tk.Button(root,text='+',width=5,font=font_16,relief=tk.FLAT,bg='#b1b2b2')button_four.grid(row=4,column=1,padx=4,pady=2)button_five.grid(row=4,column=2,padx=4,pady=2)button_six.grid(row=4,column=3,padx=4,pady=2)button_addition.grid(row=4,column=4,padx=4,pady=2)button_one = tk.Button(root,text='1',width=5,font=font_16,relief=tk.FLAT,bg='#eacda1')button_two = tk.Button(root,text='2',width=5,font=font_16,relief=tk.FLAT,bg='#eacda1')button_three = tk.Button(root,text='3',width=5,font=font_16,relief=tk.FLAT,bg='#eacda1')button_equal = tk.Button(root,text='=',width=5,font=font_16,relief=tk.FLAT,bg='#b1b2b2')button_one.grid(row=5,column=1,padx=4,pady=2)button_two.grid(row=5,column=2,padx=4,pady=2)button_three.grid(row=5,column=3,padx=4,pady=2)button_equal.grid(row=5,column=4,padx=4,pady=2)button_zero1 = tk.Button(root,text=' ',width=5,font=font_16,relief=tk.FLAT,bg='#eacda1')button_zero = tk.Button(root,text='0',width=5,font=font_16,relief=tk.FLAT,bg='#eacda1')button_dot = tk.Button(root,text='.',width=5,font=font_16,relief=tk.FLAT,bg='#eacda1')button_equal2 = tk.Button(root,text=' ',width=5,font=font_16,relief=tk.FLAT,bg='#b1b2b2')button_zero1.grid(row=6,column=1,padx=4,pady=2)button_zero.grid(row=6,column=2,padx=4,pady=2)button_dot.grid(row=6,column=3,padx=4,pady=2)button_equal2.grid(row=6,column=4,padx=4,pady=2)def click_button(x): print('X:\t',x)result_num.set(result_num.get()+x)def calculation(): opt_str = result_num.get()result = eval(opt_str)result_num.set(str(result))def btnClearDisplay(): opt_str = result_num.get()result = eval(str(opt_str))result_num.set("")button_one.config(command=lambda: click_button('1'))button_two.config(command=lambda: click_button('2'))button_three.config(command=lambda: click_button('3'))button_four.config(command=lambda: click_button('4'))button_five.config(command=lambda: click_button('5'))button_six.config(command=lambda: click_button('6'))button_seven.config(command=lambda: click_button('7'))button_eight.config(command=lambda: click_button('8'))button_nine.config(command=lambda: click_button('9'))button_zero.config(command=lambda: click_button('0'))button_dot.config(command=lambda: click_button('.'))button_addition.config(command=lambda: click_button('+'))button_subtraction.config(command=lambda: click_button('-'))button_multiplication.config(command=lambda: click_button('*'))button_division.config(command=lambda: click_button('/'))button_clear.config(command=lambda: btnClearDisplay())button_equal.config(command=calculation)root.mainloop()2. 安装PyInstaller
pip install pyinstaller
3. 用 PyInstaller 生成可执行程序
PyInstaller工具的命令语法如下:
pyinstaller <选项> <Python源文件>
不管这个 Python 应用是单文件的应用,还是多文件的应用,只要在使用 pyinstaller 命令时编译作为程序入口的 Python 程序即可。
PyInstaller工具是跨平台的,它既可以在 Windows平台上使用,也可以在 Mac OS X 平台上运行。在不同的平台上使用 PyInstaller 工具的方法是一样的,它们支持的选项也是一样的。
先创建一个文件夹(目录),在该目录下创建一个.py文件(或复制一个.py文件)。
然后转命令行窗口(cmb),进入到创建的文件夹(目录)下,执行如下命令:pyinstaller -F xxx.py
执行上面命令,将看到详细的生成过程。当生成完成后,将会在当前目录下生成一个dist目录,并在该目录下看到有一个xxx.exe文件,这就是使用PyInstaller工具生成的exe程序。
在上面命令中使用了-F选项,该选项指定生成单独的exe文件,因此,在dist目录下生成了一个单独的xxx.exe文件(在Mac OS X平台上生成的文件没有后缀);与-F选项对应的是-D选项(默认选项),该选项指定生成一个目录(包含多个文件)来作为程序。
在表1中列出的只是PyInstaller模块所支持的常用选项,如果需要了解PyInstaller选项的详细信息,则可通过pyinstaller -h来查看
4. 设置打包后的版本信息
编辑“版本信息文件”,此文件为纯文本文件,可用.txt扩展名,文件名可随意,如“file_version_info.txt”。典型的版本信息文件内容如下,中文注释是作者为方便读者学习而加的,注意红框中的项目。
说明:
1.有关固定文件信息“ffi”的更多详细信息,请参阅相关文献
2. Translation 中的语言代码,Locale ID信息见表2。
5. 编译.py文件为.exe可执行文件(有版本配置文件)
编辑“版本信息文件”,文件名随意,但需是文件文件,如“myVerInfo.txt”,内容如下:
VSVersionInfo(ffi=FixedFileInfo(filevers=(1,0,0,23),prodvers=(1,0,0,1),mask=0x3f,flags=0x0,OS=0x4,fileType=0x1,subtype=0x0,date=(0,0)),kids=[StringFileInfo([StringTable('080403a8',[StringStruct('CompanyName','解东'),StringStruct('FileDescription','计算器'),StringStruct('FileVersion','1.001'),StringStruct('InternalName','计算器.exe'),StringStruct('LegalCopyright','解东版权所有'),StringStruct('OriginalFilename','test.py'),StringStruct('ProductName','Python计算器'),StringStruct('ProductVersion','1.005')])]),VarFileInfo([VarStruct('Translation',[2052,936])])])在该目录下执行如下命令:
pyinstaller -F --version-file=myVerInfo.txt test.py
6. 执行.exe文件隐藏cmd窗口
使用 PyInstaller 的 --windowed 或 --noconsole 选项
pyinstaller -F --windowed --version-file=myVerInfo.txt test.py