• 《Python+Kivy(App开发)从入门到实践》自学笔记:打包——Windwos打包


    章节目录及知识点总览

    6.1 Windows打包

            将python程序编译成可以在windows上运行的.exe程序。

            操作过程中踩过的坑:

            1.书上使用的测试文件没找到(使用画板程序测试)

            2.通过6.1.2(普通的情况)或6.1.3(有视频的情况)编译后,exe程序运行闪退(操作到最后成功解决)

    6.1.1 打包条件  

            在打包为Windows平台可执行的EXE文件时,需要满足以下几个条件:

            使用Windows环境

            安装3.1版本以上的PyInstaller,命令为:”pip install pyinstaller

            目前支持的Kivy最高版本仅为1.9.1

     6.1.2 打包方法

            书上的这个包没找到!

            为了演示此打包方式,我们将打包Kivy自带的位于kivy-examples包下的示例项目touchtracer,并嵌入自定义图标。

            kivy-examples的安装位置默认为所使用的虚拟环境下的share文件夹,本示例位置为:“F:\pyproject\kv-demo-env\share\kivy_examples\demo\touchtracer”(该位置由官网提供,读者使用时可能会与作者的位置不同),运行该文件夹下的main.py文件即可成功查看该实例:

             使用第三章最后一篇文章的python文件进行打包测试,代码自取:《Python+Kivy(App开发)从入门到实践》自学笔记:基本图形绘制——动手实践——画板——清屏_静候光阴的博客-CSDN博客

            1.打包的基本方法

            为了打包方便,可以先将该项目文件夹复制出来,随后再打开CMD命令窗口(确保Python命令可用),通过cd命令进入到需要打包项目的同级目录下(上述位置的demo目录),执行以下命令来打包EXE文件:

    格式:python -m PyInstaller --name 输出文件名 源代码文件位置

             即:

    python -m PyInstaller --name painter painter/main.py

            执行之前,painter文件夹中放置画板所需的main.py文件及painter.kv文件,与painter文件夹同目录的icon.ico文件

            在此目录下执行上述命令: 

                    

            执行后生成两个文件夹(build及dist)及.spec文件:

     

            2.自定义图标的打包方法

            需要给打包后的文件使用自定义图标,将icon.ico文件添加到应用程序文件夹中,以便为可执行文件创建图标。如果没有.ico文件,可以使用网络应用convertio文件转换器将icon.png文件转换为.ico文件,再将icon.ico保存在touchtracer目录中,然后执行以下命令进行打包:

    格式:python - m PyInstaller --name 输出文件名 --icon ico格式图片名 源代码位置

            即:

    python -m PyInstaller --name touchtracer --icon icon.ico touchtracer/main.py

            执行完毕,exe图标变成了icon.ico图标样式

             更多打包EXE文件的选项,可以参阅官方提供的PyInstaller手册。

            3.添加依赖项

            执行完上述两条命令中的任何一条命令后,会看到生成了一个扩展名为.spec的配置文件,这时需要编辑spec文件以添加依赖项。使用编辑器打开spec配置文件,并在配置文件开头添加以下代码(假设使用了sdl2包,现在是默认设置):

    from kivy_deps import sdl2,glew

            4.添加目录数据

            然后,找到COLLECT()方法并添加touchtracer目录的数据(touchtracer.kv,particle.png),在该行中添加一个Tree树对象,例如:Tree('touchtracer'),保证spec配置文件与main.py在同级目录中,此树将搜索当前目录下的touchtracer目录中的每个文件并添加到最终的包中。

            如果要添加依赖项,请在COLLECT()方法中的第一个关键字参数之前为依赖项的每个路径添加一个Tree对象。例如:*[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],最终代码如下:

    至此,在生成的.spec源文件基础上,增加了

    1.from kivy_deps import sdl2,glew

    2.Tree('painter'),

    3.*[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],

    1. # -*- mode: python ; coding: utf-8 -*-
    2. from kivy_deps import sdl2,glew
    3. block_cipher = None
    4. a = Analysis(
    5. ['painter\\main.py'],
    6. pathex=[],
    7. binaries=[],
    8. datas=[],
    9. hiddenimports=[],
    10. hookspath=[],
    11. hooksconfig={},
    12. runtime_hooks=[],
    13. excludes=[],
    14. win_no_prefer_redirects=False,
    15. win_private_assemblies=False,
    16. cipher=block_cipher,
    17. noarchive=False,
    18. )
    19. pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
    20. exe = EXE(
    21. pyz,
    22. a.scripts,
    23. [],
    24. exclude_binaries=True,
    25. name='painter',
    26. debug=False,
    27. bootloader_ignore_signals=False,
    28. strip=False,
    29. upx=True,
    30. console=True,
    31. disable_windowed_traceback=False,
    32. argv_emulation=False,
    33. target_arch=None,
    34. codesign_identity=None,
    35. entitlements_file=None,
    36. icon='icon.ico',
    37. )
    38. coll = COLLECT(
    39. exe,Tree('painter'),
    40. a.binaries,
    41. a.zipfiles,
    42. a.datas,
    43. *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
    44. strip=False,
    45. upx=True,
    46. upx_exclude=[],
    47. name='painter',
    48. )

    现在使用以下命令打包一个EXE文件:

    (其中需要重新覆盖掉dist文件夹内的数据,需要手动输入'y'确认操作):

    python -m PyInstaller painter.spec

             编译完成后的程序包位于\dist\painter中,将整个包复制出来,直接运行painter.exe文件,结果与通过Kivy直接运行的main.py文件一致:

    6.1.3 添加依赖

            在一般情况下,通过gstreamer框架来打包视频应用程序。将略微修改6.1.2小节实例中的打包方法,实现使用gstreamer将视频应用程序打包

            实例:打包前添加依赖

            使用高级UX部件——VideoPlayer视频播放示例文件打包,新建一个gstvideo文件夹,里面添加videoplayer.py(测试能够正常运行后再打包)。在CMD命令行窗口中通过cd命令进入到gstvideo外的目录并执行以下命令:

    python -m PyInstaller --name gstvideo gstvideo\videoplayer.py

             命令执行完成后会生成gstvideo.spec配置文件。编辑该配置文件,添加一个gstreamer依赖项,具体配置如下:

    注意:添加gstreamer依赖提示import错误时,使用命令:pip install kivy_deps.gstreamer

     至此,gstvideo.spec配置文件内添加内容包括了:

            1.from kivy_deps import sdl2,glew,gstreamer

            2.Tree('gstvideo'),

            3. *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins + gstreamer.dep_bins)],

    1. # -*- mode: python ; coding: utf-8 -*-
    2. from kivy_deps import sdl2,glew,gstreamer
    3. block_cipher = None
    4. a = Analysis(
    5. ['gstvideo\\videoplayer.py'],
    6. pathex=[],
    7. binaries=[],
    8. datas=[],
    9. hiddenimports=[],
    10. hookspath=[],
    11. hooksconfig={},
    12. runtime_hooks=[],
    13. excludes=[],
    14. win_no_prefer_redirects=False,
    15. win_private_assemblies=False,
    16. cipher=block_cipher,
    17. noarchive=False,
    18. )
    19. pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
    20. exe = EXE(
    21. pyz,
    22. a.scripts,
    23. [],
    24. exclude_binaries=True,
    25. name='gstvideo',
    26. debug=False,
    27. bootloader_ignore_signals=False,
    28. strip=False,
    29. upx=True,
    30. console=True,
    31. disable_windowed_traceback=False,
    32. argv_emulation=False,
    33. target_arch=None,
    34. codesign_identity=None,
    35. entitlements_file=None,
    36. )
    37. coll = COLLECT(
    38. exe,Tree('gstvideo'),
    39. a.binaries,
    40. a.zipfiles,
    41. a.datas,
    42. *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins + gstreamer.dep_bins)],
    43. strip=False,
    44. upx=True,
    45. upx_exclude=[],
    46. name='gstvideo',
    47. )

            编辑完成.spec配置文件后,使用以下命令打包该项目:(过程中提示是否覆盖dist文件加内数据,选'Y')

    python -m PyInstaller gstvideo.spec

             编译后,位于dist\gstvideo\gstvideo.exe,可以正常执行,效果跟.py文件执行效果一致,具体如下图:        

            注意:由于Kivy的#1638BUG尚未解决,那么如果使用了Pygame包,则必须在spec配置文件中导入后,再添加以下代码:【未验证】

    1. def getResource(identtifer,*args,**kwargs):
    2. if identifier == 'Pygame_icon.tiff':
    3. raise IOError()
    4. return _original_getResource(identifier,*args,**kwargs)
    5. import pygame.pkgdata
    6. _original_getRecource = pygame.pkgdata.getResource
    7. pygame.pkgdata.getResource = getResource

     6.1.4 自定义安装

            在使用PyInstalle模块打包时,除了安装所需的依赖外,默认情况下还会添加Kivy使用的所有核心模块,例如音频、视频、拼写等。此时打包出来的应用程序时非常大的,为了减小应用程序大小,可以排除其中的一部分模块,例如音频、视频等,所以Kivy提供了hookspath()方法。

            在使用hookspath()方法时,不会包含任何Kivy提供的程序,如果要添加它们,必须使用get_deps_minimal()或者get_deps_all()方法。但实际上,get_deps_all()方法同使用默认的方法一样,会添加所有Kivy提供的程序,而get_deps_minmal()方法仅添加在运行应用时加载的程序。但无论使用哪种方法,Kivy都提供了添加(即需要打包进来的)的列表和排除的列表,一般会在spec文件的Analysis包中配置。

            实例:设置打包自定义安装

            复制6.1.3小节的项目,并生成spec配置文件,将实例中的代码修改成如下所示:

    1.添加from kivy.tools.packaging.pyinstaller_hooks import get_deps_minimal,get_deps_all,hookspath,runtime_hooks

    2.将hookspath=[]改为hookspath=hookspath()

    1. # -*- mode: python ; coding: utf-8 -*-
    2. from kivy_deps import sdl2,glew,gstreamer
    3. from kivy.tools.packaging.pyinstaller_hooks import get_deps_minimal,get_deps_all,hookspath,runtime_hooks
    4. block_cipher = None
    5. a = Analysis(
    6. ['gstvideo\\videoplayer.py'],
    7. pathex=[],
    8. binaries=[],
    9. datas=[],
    10. hiddenimports=[],
    11. hookspath=hookspath(),
    12. hooksconfig={},
    13. runtime_hooks=[],
    14. excludes=[],
    15. win_no_prefer_redirects=False,
    16. win_private_assemblies=False,
    17. cipher=block_cipher,
    18. noarchive=False,
    19. )
    20. pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
    21. exe = EXE(
    22. pyz,
    23. a.scripts,
    24. [],
    25. exclude_binaries=True,
    26. name='gstvideo',
    27. debug=False,
    28. bootloader_ignore_signals=False,
    29. strip=False,
    30. upx=True,
    31. console=True,
    32. disable_windowed_traceback=False,
    33. argv_emulation=False,
    34. target_arch=None,
    35. codesign_identity=None,
    36. entitlements_file=None,
    37. )
    38. coll = COLLECT(
    39. exe,Tree('gstvideo'),
    40. a.binaries,
    41. a.zipfiles,
    42. a.datas,
    43. *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins + gstreamer.dep_bins)],
    44. strip=False,
    45. upx=True,
    46. upx_exclude=[],
    47. name='gstvideo',
    48. )

            在spec配置文件中依然添加导入语句,再修改Analysis包,并使用**get_dep_minimal()或**get_deps_all()方法制定添加或排除的程序包。

    上一篇:高级UX部件——VKeyboard键盘

    下一篇:OS X 打包

  • 相关阅读:
    忘记Docker的NextCloud密码
    力扣(LeetCode)算法_C++——至多包含两个不同字符的最长子串
    51单片机学习:ADC模数转换实验--光敏电阻AD采集
    java毕业设计糖助手服务交流平台mybatis+源码+调试部署+系统+数据库+lw
    E. Beautiful Subarrays(Trie维护前缀异或和)
    【我的前端】前端项目小练习:CSS创建3D圆柱旋转效果
    PIE-Engine APP:凉山州火灾高发地异常度分析系统
    PostgreSQL 同步复制原理解析
    Flask生成图片验证码的功能
    Android studio:打开应用程序闪退的问题
  • 原文地址:https://blog.csdn.net/lstef/article/details/127721939