pyinstaller打包exe和踩过的坑

1、pycharm创建python虚拟环境

(我目前创建的虚拟环境是基于python3.8的环境创建的)(一定创建虚拟环境,我开始用python38环境,打包删除都非常慢,耗时太久)

2、项目根目录下生成requirements.txt

3、项目下执行 pip install -r requirements.txt

4、编辑如下配置文件

5、datas下的任何一个目录里不能是空文件夹,不然打包不进去

-*- mode: python ; coding: utf-8 -*-

block_cipher = None

a = Analysis(

['main.py',

'catchLog.py',

'common\\adb_connect_devices.py' ,

'utils\\board.py',

'utils\\running_circle.py',

'utils\\threads.py'],

pathex=['D:\\DB_Programs\\ZhuanXiangTest\\Test\\log_tool'],

binaries=[],

datas=[('utils','utils'),('common','common'),('file','file'),('catchLog.py','.')],

hiddenimports=[],

hookspath=[],

hooksconfig={},

runtime_hooks=[],

excludes=[],

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,

[],

exclude_binaries=True,

name='main',

debug=False,

bootloader_ignore_signals=False,

strip=False,

upx=True,

console=True,

disable_windowed_traceback=False,

argv_emulation=False,

target_arch=None,

codesign_identity=None,

entitlements_file=None,

icon='D:\\DB_Programs\\ZhuanXiangTest\\Test\\log_tool\\file\\icons\\Logo.png',

)

coll = COLLECT(

exe,

a.binaries,

a.zipfiles,

a.datas,

strip=False,

upx=True,

upx_exclude=[],

name='main',

)

暂时无法在飞书文档外展示此内容

5、pip install pyinstaller

6、执行pyinstaller main.spec

踩坑:

踩坑1:之前项目目录有中文,创建了虚拟环境(如下红色路径)。怕打包中文会报错。把路径改成了英文的,pycharm也修改了python解释器的路径。但是编译打包exe文件时还是显示之前的中文路径。

解决办法:删除上面创建的虚拟环境(删除venv目录即可删除虚拟环境),基于3.8创建一个新的虚拟环境。重新打包就不会会出现路径不一致了。

踩坑2:

执行编译后的exe,报AttributeError: module 'serial' has no attribute 'Serial'错误。

解决办法:

卸载之后重新安装两个第三方库文件:pip3 uninstall serial和pip3 uninstall pyserial,卸载之后就可以重 新安装(本人尝试过,这种方法,可用)

踩坑3:

打包后其它电脑执行报错如下

解决办法:

1、卸载pyqt5后重新安装

2、pip install PyQt5 -i https://pypi.douban.com/simple

3、pip install PyQt5-tools -i https://pypi.douban.com/simple ( pip install pyqt5-tools,这个是重点。需要这个工具依赖。pyqt5 下载有附加工具 pyqt5-tools需要同步下载

4、将项目目录下的venv\Lib\site-packages 里面的PyQt5、pyqt5_plugins包复制到venv\Lib下

踩坑4:

解决办法:

4.1、不要在init初始化serial.Serial()

4.2、在实际调用的地方初始化serial.Serial()

4.5 解决python调用cmd命令或第三方exe时出现cmd黑框

在Windows环境下,python程序中会调用cmd命令或第三方exe文件,很多时候要么会直接打开cmd黑框显示完整的运行过程,要么会显示一个无内容显示的cmd黑框。

举例1:使用os.system调用ping http://www.baidu.com之类的命令,然后返回调用结果。调用的过程中,会出现完整的ping命令黑框执行全过程;

举例2:使用os.popen方式调用静默打印pdf文件的exe,调用过程中,会出现一个无内容的cmd黑框,在打印完成后才会消失。

整体思路,使用subprocess代替os模块,如下总结了几种可以解决上述黑框的方法,以下在windows环境下测试通过:

不需要返回,只是调用程序或命令

run方式默认为阻塞方式,即需要等调用命令完成后才会接着运行python下一步代码:

def run_cmd( cmd_str:str): from subprocess import run

run(cmd_str, shell=True) shell=True是关键,需要加上,否则还是会有黑框print('需要等上述命令完成后,才会显示这一行")

run_cmd("ping www.baidu.com") 调用自定义函数测试阻塞run_cmd('notepad') 会打开一个记事本程序,需要手工关闭记事本后才会显示print内容

得到调用程序执行后的输出详细结果:

 

def run_cmd(cmd_str:str):import subprocessreturn subprocess.Popen(cmd_string, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True).communicate()[0]print(run_cmd('ping www.baidu.com'))

其中:text=True,可以将输出结果变为文字,且避免选择编码格式

subprocess.Popen()方法为一个非阻塞方法,因此需要使用communicate()进行阻塞获取输出结果,与wait()的区别在于:wait()默认pipe size为64KB,超出限制容易导致死锁;而communicate()会将输出放在内存中,上限与可分配的内存相关

得到调用程序执行后的返回值

(即表示程序运行是否成功的标志,不返回详细程序输出值)

def run_cmd(cmd_str:str):import subprocessreturn subprocess.Popen(cmd_str, shell=True, stdout=None, stderr=None).wait()print(run_cmd('ping www.baidu.com'))返回0表示程序执行成功不要if not run_cmd('ping www.baidu.com'): 这样来判断执行成功做一个超时强行关闭pipe机制后,返回的结果为None,用逻辑判断的结果和0是一样的,但其实是运行不成功的

subprocess.Popen的典型参数:

p=subprocess.Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True, Text=True, cwd='d:/')

其中:

args即为传入要运行的命令或程序,有两种形式:

['ping','www.baidu.com','-t'] # 用list方式分隔命令参数

'ping www.baidu.com -t' # 注意参数如包含空格,应使用类似'"xxxxx"'来处理

cwd传入一个绝对路径,会将传入的命令或程序工作目录改为cwd

returncode属性,返回传入运行的命令或程序exit code,运行正常为0

p.communicate()

p.returncode

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值