打包python为mac应用
1、安装py2app,打开终端,执行
pip install py2app
2、在桌面新建一个文件夹,取名xxx,打包的程序baba.py放在里面
3、进入终端,切路径至该文件夹下,执行
py2applet --make-setup baba.py
4、开始打包应用,执行
python setup.py py2app
5、xxx文件下出现dist文件夹,打开后里面有个app,双击即可运行
五、在 setup.py 文件中手动输入需要的依赖
如果项目很简单,没有导入第三方库和自建模块,可以忽略此步骤。
下面是 setup.py 文件的一个例子,手动输入的部分就是在 DATA_FILES 空列表里加自建模块的名字,在 OPTIONS 字典的 includes 对应的空列表中加第三方模块的名字
# python自带的库无需输入,第三方库和自己引入的自写模块需要输入
"""
This is a setup.py script generated by py2applet
Usage:
python setup.py py2app
"""
from setuptools import setup
# 放置要执行py的列表
APP = ['start.py']
# 存放所有要用到的文件资源,比如我放置了py_utils/这个是工具包文件夹,app所要显示的图片文件,以及自写模块放
DATA_FILES = ['py_utils/', 'earth.icns', 'xxx1.py','xxx2.py','xxx3.py']
# 可选参数。
# iconfile:app的图标,必须为icns的格式,其他格式的话是不会显示出来的
# includes: A list of Python modules to include even if they are not detected by dependency checker. Packages in this list are ignored.
# includes: 第三方库放在这里。
# plist:其他的app应用配置,熟悉MACOS应用开发的都会非常熟悉这些参数,mac应用info.plist里的参数都可以添加进去
OPTIONS = {'iconfile':'earth.icns',
'plist': {
'CFBundleName' : 'verify', # 应用名
'CFBundleDisplayName': 'verify', # 应用显示名
'CFBundleVersion': '1.0.0', # 应用版本号
'CFBundleIdentifier' : 'verify', # 应用包名、唯一标识
'NSHumanReadableCopyright': 'Copyright © 2021 SW Felix.Zhao. All rights reserved.', # 可读版权
'includes': ['sip', 'PyQt5.QtCore', 'PyQt5.QtWidgets']
}
}
setup(
app=APP,
data_files=DATA_FILES,
options={'py2app': OPTIONS},
setup_requires=['py2app'],
)
具体OPTIONS中的参数怎么用,参考官方文档:py2app Options - py2app 0.27 documentation
六、生成 app
# 自己开发,打包速度快。(因为本机安装了依赖库,所以可以直接运行)
python setup.py py2app -A
# 给其他没有 sdk 的电脑使用,包括 lib 库。(没有安装 sdk 的电脑使用,需要去掉 -A,将把所有的依赖全部打包。)
python setup.py py2app
之后会生成 build 和 dist 两个文件夹,启动文件在 dist 下,双击就可以执行。
注:如果发现有问题,在重新进行上述步骤前最好先删除 build 和 dist 两个文件夹。
rm -rf build dist
如上图,这里删除的两个文件夹其实就是上一次打包的时候,生成的两个文件夹。
七、Debug
有些情况下,我们打包完的程序,双击运行会报错。如下图所示:
这时候,我们需要采取特殊的运行方法来 debug。
我们在 dist 文件夹下面,右键我们的 app 程序,点击 show package contents。这时候我们会发现新打开了一个文件夹,这个文件夹里面储存着这个 app 的所有信息。
在 Mac OS 这个文件夹下面,有一个没有后缀的文件是和你想要打包的 py 文件同名的。双击它和直接双击我们的 app 程序,背后执行的主体代码是一样的,但是它打开的方式却是在终端里打开,因此在终端里显示的报错信息就可以帮助我们 debug。
如上图,以我自己的运行结果举例,报错是因为没有 rpath 下面的 libffi.8.dylib这个文件。
因此,我在 Mac 上搜索这个文件(如上图),找到对应的虚拟环境下面的那个版本,复制到 Frameworks 文件夹下面(如下图)。
这时候再运行,就不会报错了。
解决这个问题参照了:关于dyld: Library not loaded那点事儿
官方文档中关于 debug 的教程:Debugging application building
最终卡在debug这个环节,mac的环境好像有很多不兼容的地方,后面再琢磨吧,暂时放在一边 😭!
1. Grails
Grails是一套用于快速Web应用开发的开源框架,它基于Groovy编程语言,并构建于Spring、Hibernate等开源框架之上,是一个高生产力一站式框架
2. VUE, spring boot
web前端框架系统
Nginx + uWSGI + VUE + DRF + MySQL / Redis
3. .net core
.NET 是一种用于构建多种应用的免费开源开发平台,例如:
- Web 应用、Web API 和微服务
- 云中的无服务器函数
- 云原生应用
- 移动应用
- 桌面应用
- Windows WPF
- Windows 窗体
- 通用 Windows 平台 (UWP)
- 游戏
- 物联网 (IoT)
- 机器学习
- 控制台应用
- Windows 服务
4. Django
是以Python需要写的后端为主的web服务框架,用于编写业务逻辑,连接数据库,提供给VUE前端显示
5. 爬虫
6. mysql / redis
MySQL免费的关系型数据库,redis非关系型数据库,构建CRM系统的方法,这是一个具体实战的项目,将用到所有学到的东西
7. 图片自动转pdf文件
from fpdf import FPDF # pdf生成模块
from PIL import Image
import os
BASE_DIR = ‘/Users/wongbrank/Desktop/make_pdf’
def join_path(filename):
return os.path.join(BASE_DIR,filename)
def makePDF(filename, images):
_# cover = Image.open(join_path(images[0]))
# width, height = cover.size
_pdf = FPDF(unit=**'pt'**,format=[1000,1403]) # 新建一个pdf对象,format 宽高 unit 长宽单位 <br /> print(**'initing ... '**) # 这一步没有必要
**for **page **in **images:<br /> pdf.add_page() # 增加一个页面 <br /> pdf.image(join_path(page),0,0,1000,1403) # 插入图片到页面,图片路径,左上角定位,长,宽
pdf.output(join_path(filename), **'F'**) # 输出 存储文件路径, F:输入到本地文件
images = [ item for item in os.listdir(‘/Users/wongbrank/Desktop/make_pdf’) if item.rsplit(‘.’)[-1] in (‘jpeg’,‘jpg’,‘gif’,’png’) ]
print(images)
makePDF(‘result.pdf’, images)
小知识点:
os.listdir('/Users/wongbrank/Desktop/make_pdf') # 获取目录列表
在mac中使用Python程序:
在pycharm环境中编写完毕以后,运行程序不报错,然后在运行窗口中找到第一行执行命令的原文,
然后vim制作一个xxx.command的批处理文件,存入命令行,chmod +x 赋予它可执行权限,然后双击运行
8. pdf加密
# 如果没有包PyPDF2, 直接pip3 install PyPDF2
# 给pdf文档加密
from PyPDF2 import PdfFileWriter, PdfFileReader
filename = r"/Users/wongbrank/Desktop/6页编制表 1.pdf"
out_filename = filename.rsplit('.')[0] + '加密.pdf'
pwd = input('请输入加密密码: ')
pdf_reader = PdfFileReader(filename) # 创建pdf读对象
pdf_writer = PdfFileWriter() # 创建pdf写对象
# 依次把文件读入到写对象
for page in range(pdf_reader.getNumPages()):
pdf_writer.addPage(pdf_reader.getPage(page))
# pdf_writer.appendPagesFromReader(pdf_reader) # 这句直接取代上面的循环写法
# 加密
pdf_writer.encrypt(pwd)
# 输出
with open(out_filename, 'wb') as f:
pdf_writer.write(f)