目录
为Windows创建一个包。¶
备注
本文档仅适用于Kivy 1.9.1 及以上版本。
在Windows平台上打包应用程序只能在Windows操作系统内进行。以下流程已在Windows上使用Kivy **wheels**安装进行了测试,其他安装方式请参见文末。
该软件包将是32位或64位,具体取决于您运行它时使用的Python版本。
要求¶
最新版Kivy(按照:ref:`installation_windows`中描述的方式安装)。
PyInstaller 3.1+(
pip install --upgrade pyinstaller)。
PyInstaller 默认钩子¶
本节内容适用于包含kivy钩子的PyInstaller(>=3.1)。若要覆盖默认钩子,以下示例需稍作修改。参见:ref:overwrite-win-hook。
打包一个简单的应用¶
在本示例中,我们将打包**touchtracer**示例项目,并嵌入自定义图标。当使用wheel包安装时,Kivy示例位于``python\share\kivy-examples``;若从GitHub源码安装,则位于``kivy\examples``。我们将指向示例的完整路径简称为``examples-path``。touchtracer示例位于``examples-path\demo\touchtracer``,主文件名为``main.py``。
打开你的命令行终端,并确保Python已在系统路径中(即输入``python``命令可以正常工作)。
创建一个文件夹,用于存放打包后的应用程序。例如,创建一个``TouchApp``文件夹,并使用例如``cd TouchApp``命令`切换到该目录 <https://www.computerhope.com/cdhlp.htm>`_。然后输入:
python -m PyInstaller --name touchtracer examples-path\demo\touchtracer\main.py
你也可以在应用程序文件夹中添加一个 icon.ico 文件,以便为可执行文件创建图标。如果你没有可用的 .ico 文件,可以使用网页应用 ConvertICO 将你的 icon.png 文件转换为 ico 格式。将 icon.ico 保存在 touchtracer 目录中,然后输入:
python -m PyInstaller --name touchtracer --icon examples-path\demo\touchtracer\icon.ico examples-path\demo\touchtracer\main.py
更多选项,请参阅 PyInstaller 手册。
规格文件将是位于``TouchApp``中的``touchtracer.spec``。现在我们需要编辑规格文件,添加依赖钩子以正确构建exe。用你喜欢的编辑器打开规格文件,并在规格文件的开头添加以下行(假设使用sdl3,现在默认如此):
from kivy_deps import sdl3, glew
然后,找到``COLLECT()``并为touchtracer(touchtracer.kv、particle.png`等)添加数据:修改该行以添加一个``Tree()``对象,例如``Tree('examples-path\demo\touchtracer\')`。这个Tree将搜索并添加touchtracer目录中找到的每个文件到你的最终包中。
要添加依赖项,请在COLLECT中的第一个关键字参数之前,为每个依赖路径添加一个Tree对象。例如:
*[Tree(p) for p in (sdl3.dep_bins + glew.dep_bins)],这样看起来会像这样:coll = COLLECT(exe, Tree('examples-path\\demo\\touchtracer\\'), a.binaries, a.zipfiles, a.datas, *[Tree(p) for p in (sdl3.dep_bins + glew.dep_bins)], strip=False, upx=True, name='touchtracer')
现在我们在
TouchApp中构建规格文件,如下所示:python -m PyInstaller touchtracer.spec
编译后的包将位于 TouchApp\dist\touchtracer 目录中。
单文件应用程序¶
接下来,我们将修改上述示例,将 touchtracer 示例项目打包为单文件应用程序。按照上述相同步骤,改为执行以下命令:
python -m PyInstaller --onefile --name touchtracer examples-path\demo\touchtracer\main.py
和之前一样,这将生成touchtracer.spec文件,我们将编辑该文件以添加依赖项。在此实例中,编辑EXE命令的参数,使其看起来类似如下:
exe = EXE(pyz, Tree('examples-path\\demo\\touchtracer\\'), a.scripts, a.binaries, a.zipfiles, a.datas, *[Tree(p) for p in (sdl3.dep_bins + glew.dep_bins)], upx=True, name='touchtracer')
现在你可以像之前一样构建spec文件,使用:
python -m PyInstaller touchtracer.spec
编译后的包将位于`TouchApp\dist`目录中,由单个可执行文件组成。
打包数据文件¶
我们将再次修改之前的示例,以包含打包的数据文件。PyInstaller允许包含项目运行所需的外部数据文件(如图像、数据库等)。在Windows上运行应用时,可执行文件会解压到一个临时文件夹,而Kivy项目并不知道这个位置,因此无法定位这些数据文件。我们可以通过几行代码来解决这个问题。
首先,请遵循PyInstaller文档中关于如何在应用程序中包含数据文件的说明。
修改你的主 Python 代码,使其包含以下导入(如果尚未包含的话):
import os, sys from kivy.resources import resource_add_path, resource_find
修改你的主 Python 代码,使其包含以下内容(以 touchtracer 应用为例):
if __name__ == '__main__': if hasattr(sys, '_MEIPASS'): resource_add_path(os.path.join(sys._MEIPASS)) TouchtracerApp().run()
最后,按照上述步骤打包你的应用程序。
使用 GStreamer 打包视频应用¶
接下来,我们将稍微修改上面的示例,以打包一个使用gstreamer进行视频播放的应用。我们将使用位于``examples-pathwidgetsvideoplayer.py``的``videoplayer``示例。在某个位置创建一个名为``VideoPlayer``的文件夹,并在命令行中将当前目录切换到该文件夹,然后执行:
python -m PyInstaller --name gstvideo examples-path\widgets\videoplayer.py
要创建``gstvideo.spec``文件。按上述方式编辑,这次同时包含gstreamer依赖项:
from kivy_deps import sdl3, glew, gstreamer
并添加 Tree() 以包含视频文件,例如 Tree('examples-path\\widgets'),以及 gstreamer 依赖项,因此它应该看起来像这样:
coll = COLLECT(exe, Tree('examples-path\\widgets'),
a.binaries,
a.zipfiles,
a.datas,
*[Tree(p) for p in (sdl3.dep_bins + glew.dep_bins + gstreamer.dep_bins)],
strip=False,
upx=True,
name='gstvideo')
然后在 VideoPlayer 中构建 spec 文件,使用:
python -m PyInstaller gstvideo.spec
你应该能在 VideoPlayer\dist\gstvideo 中找到 gstvideo.exe,运行它即可播放视频。
覆盖默认钩子¶
包含/排除视频和音频以及减小应用体积¶
PyInstaller 包含一个针对 Kivy 的钩子,默认会添加 Kivy 使用的**所有**核心模块,例如音频、视频、拼写等(你仍然需要使用 Tree() 手动打包 gstreamer DLL——参见上面的示例)及其依赖项。如果该钩子未安装,或为了减小应用体积,可以通过替代钩子排除其中一些模块,例如,如果不使用音频/视频。
Kivy 在 hookspath() 处提供了备用钩子。此外,当且仅当 PyInstaller 没有默认钩子时,还必须提供 runtime_hooks()。在覆盖钩子时,通常不需要覆盖后者。
备选的 hookspath() 钩子不包含任何 Kivy 提供者。要添加它们,必须通过 get_deps_minimal() 或 get_deps_all() 来添加。更多详情请参阅它们的文档和 pyinstaller_hooks。但本质上,get_deps_all() 会像默认钩子一样添加所有提供者,而 get_deps_minimal() 仅添加应用运行时加载的那些提供者。每种方法都会提供一个隐藏的 Kivy 导入和排除导入的列表,这些可以传递给 Analysis。
也可以生成一个备用的钩子,它逐一列出所有Kivy提供者模块,不需要的模块可以注释掉。参见 pyinstaller_hooks。
要使用上述示例中的备用钩子,请按以下方式修改,通过``hookspath()``和``runtime_hooks``(如需要)添加钩子,并使用``**get_deps_minimal()``或``**get_deps_all()``来指定提供者。
例如,添加导入语句:
from kivy.tools.packaging.pyinstaller_hooks import get_deps_minimal, get_deps_all, hookspath, runtime_hooks
然后按如下方式修改 Analysis:
a = Analysis(['examples-path\\demo\\touchtracer\\main.py'],
...
hookspath=hookspath(),
runtime_hooks=runtime_hooks(),
...
**get_deps_all())
要包含所有内容,就像默认钩子一样。或者:
a = Analysis(['examples-path\\demo\\touchtracer\\main.py'],
...
hookspath=hookspath(),
runtime_hooks=runtime_hooks(),
...
**get_deps_minimal(video=None, audio=None))
例如,要排除音频和视频提供者,而对于其他核心模块,仅使用已加载的那些。
关键点在于提供备选的 hookspath(),它默认不列出所有 Kivy 提供者,而是通过 get_deps_minimal() 手动将所需的提供者添加到 hiddenimports,同时移除不需要的提供者(在此示例中为音频和视频)。
其他安装方式¶
之前的示例使用了如 *[Tree(p) for p in (sdl3.dep_bins + glew.dep_bins + gstreamer.dep_bins)], 这样的代码,以便让 PyInstaller 添加这些依赖项所使用的所有 DLL 文件。如果 Kivy 不是通过 wheels 方法安装的,这些命令将无法正常工作,例如 kivy_deps.sdl3 将无法导入。在这种情况下,必须找到这些 DLL 文件的位置,并以与示例类似的方式手动将它们传递给 Tree 类。