前文PyQt5系列教程(四)用py2exe进行程序打包介绍了如何使用py2exe
来给python3
工程打包,本文介绍另一个打包工具pyinstaller
,个人感觉比py2exe
更加简单、方便,而且还跨平台。
命令行中执行
pip install pyinstaller
示例还是以之前的为例,解压进入工程目录,命令行执行打包命令
pyinstaller -F --distpath release main.py
其中release
是目标文件夹,main.py
是工程入口文件,-F
表示生成一个可执行文件。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IMP14Y2q-1571620002958)(https://code.xugaoxiang.com/xugaoxiang/blog/raw/master/images/python/pyqt5/9-pyinstaller-02.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7tKJA8la-1571620002961)(https://code.xugaoxiang.com/xugaoxiang/blog/raw/master/images/mac/PyQt5/9-pyinstaller-03.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SikbYWSV-1571620002962)(https://code.xugaoxiang.com/xugaoxiang/blog/raw/master/images/mac/PyQt5/pyinstaller-01.png)]
pyinstaller
的打包参数很多,需要的话通过help
来查看
pyinstaller -h
在打包包含subprocess.Popen
时发现,加上参数--noconsole
时产生的exe
文件在运行的时候,进程并没有正确运行。比如需要利用subprocess.Popen
创建一个进程去执行一个命令行操作,
mProcess = subprocess.Popen(cmd,stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,universal_newlines=True)
pyinstaller
打包操作命令如下
pyinstaller -F --noconsole --clean --distpath release main.py
打包后生成的exe
,可以运行,不过查看进程并没有如预期正确地工作。
解决方法是在创建进程时,加上startupinfo
参数,如下
si = subprocess.STARTUPINFO()
si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
mProcess = subprocess.Popen(cmd,stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,universal_newlines=True,startupinfo=si)
问题完美解决,具体可以参考文末的资料
项目中用到了apscheduler
这个库,用来做定时任务非常的好,使用也很简单,不过在pyinstaller
打包的时候,出现了如下错误
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3NElAniO-1571620002963)(https://code.xugaoxiang.com/xugaoxiang/blog/raw/master/images/python/pyqt5/9-pyinstaller-apscheduler-01.png)]
解决方法是,编辑文件/usr/local/lib/python3.5/dist-packages/apscheduler/__init__.py
# These will be removed in APScheduler 4.0.
# release = __import__('pkg_resources').get_distribution('APScheduler').version.split('-')[0]
# version_info = tuple(int(x) if x.isdigit() else x for x in release.split('.'))
# version = __version__ = '.'.join(str(x) for x in version_info[:3])
release = (3,3,1)
version_info = '3.3.1'
version = '3.3.1'
3.3.1
是我安装的apscheduler
的版本号,视实际情况修改。
接下来创建一个名称为hook-ctypes.macholib.py
,内容如下
# -*- coding: utf-8 -*-
from PyInstaller.utils.hooks import copy_metadata
datas = copy_metadata('apscheduler')
最后执行打包命令
pyinstaller -F --clean --additional-hooks-dir hooks --distpath release main.py
在用pyinstaller
打包一个使用了sqlalchemy
库的python3
工程中,碰到了打包后的可执行文件报错的问题,如下图所示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6q6u8u9v-1571620002963)(https://code.xugaoxiang.com/xugaoxiang/blog/raw/master/images/python/pyqt5/9-pyinstall-sqlalchemy-01.png)]
解决方案是,将sqlalchemy.dialects
中的mysql
引入,然后采用mysql+pymysql
的方式打开数据库,代码如下
import pymysql
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.dialects import mysql
username = 'xugaoxiang'
passwd = '123456'
server = '192.168.0.100'
port = '3306'
dbname = 'djdb'
cmd_connect = 'mysql+pymysql://{}:{}@{}:{}/{}'.format(username, passwd, server, port, dbname)
engine = create_engine(cmd_connect)
执行pyinstaller
打包命令
pyinstaller -F --clean --distpath shark main.py
为了便于保存记录,在Github
创建了一个工程,地址是: https://github.com/xugaoxiang/learningPyQt5,后续会把所有的代码、文档以及博文链接都放在上面。