python - Kivy到一个exe找不到kv文件
问题描述
我在这里看到了一些相关的问题,并尝试了我发现的每一个解决方案,例如这个和这个,但我无法做到这一点。所以问题很简单——从 kivy 制作单个 exe 文件后,它会抛出一个FileNotFoundError: [Errno 2] No such file or directory: 'main2.kv'
. 带有相关文件的 exe 文件效果很好,但我不知道在构建单个 exe 时我做错了什么。
我的规格文件:
# -*- mode: python ; coding: utf-8 -*-
from kivymd.tools.packaging.pyinstaller import hooks_path as kivymd_hooks_path
from kivy_deps import sdl2, glew
...
a = Analysis(['main.py'],
...
# I tried to write here absolute path, relative path and this method
datas=[('*.kv', '.')],
hiddenimports=[],
hookspath=[kivymd_hooks_path],
...
)
# I also tried to put import here - didn't help (when I did that I also tried to change the path in my .py file to 'Data\main2.kv')
# a.datas += [('main2.kv', 'D:\\prog\\Lotto\\main2.kv', 'DATA')]
...
# tried with Tree and without Tree
coll = COLLECT(exe, Tree('D:\\prog\\Lotto','Data'),
...
*[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
...
在 .py 文件中我尝试添加
if getattr(sys, 'frozen', False):
kivy.resources.resource_add_path(sys._MEIPASS)
和
def resourcePath():
if hasattr(sys, '_MEIPASS'):
return os.path.join(sys._MEIPASS)
return os.path.join(os.path.abspath("."))
...
if __name__ == "__main__":
kivy.resources.resource_add_path(resourcePath())
MainApp().run()
并同时尝试了上述两种方法 - 没有。还尝试将 PyInstaller 3.6 更改为 3.5 版本。我不知道这里有什么问题,这是我第一次尝试从 Kivy 制作 exe 文件。
解决方案
几个小时后,我终于明白了。我首先打开我的 kv 文件file
,然后将其传递Builder
给能够设置编码。在那种情况下,我只需要kv
手动定义文件的路径,sys._MEIPASS + 'main2.kv'
然后它就可以工作了。
UPD:为了使这项工作首先进行少量进口:
import os, sys
from kivy.resources import resource_add_path
然后在您的应用程序末尾 MainApp.run() 之前添加以下内容:
if __name__ == "__main__":
# these lines should be added
if hasattr(sys, '_MEIPASS'):
resource_add_path(os.path.join(sys._MEIPASS))
###
MainApp().run()
当我们构建单个 .exe 文件时,它会在其中保存所有文件,因此它会在运行时将其解压缩到某个随机的临时文件夹中。sys._MEIPASS
这是该临时文件夹的路径。
所以这应该有效。如果它仍然找不到文件,您可以尝试像这样更改文件路径:例如,而不是'example.kv'
write sys._MEIPASS + '/' + 'example.kv'
。
还要确保您已在 .spec 文件中正确完成所有操作,因此您应该将文件添加到datas
列表中,Analysis
如下所示:
a = Analysis(['main.py'],
...
datas=[('main.kv', '.'), ('bg.png', '.'), ('CenturyGothic.ttf', '.'), ('finish.mp3', '.'), ('Logo.png', '.'),],
因此,如果您只有kv
要添加的文件,它将是:
datas=[('main.kv', '.')],
推荐阅读
- jasmine - 如何在茉莉花的可观察对象中为 http-post 编写单元测试?
- java - 在 Spring Boot 日志记录中使用外部 JUL“logging.properties”
- apache-spark - 将 Spark RDD 分成 N 个子部分,多次迭代时保持不变
- amazon-web-services - 如何在 .ebextensions 中获取负载均衡器的 ARN?
- html - 如何根据内容自动调整 HTA 窗口的大小
- angular - 类型“未知”不可分配给类型“T”
- c - 如何将函数中数组的大小传递给函数?我没有“可变大小的对象可能未初始化”
- ios - 安全 WebSocket WSS(自签名证书)在 iOS Safari 上不起作用
- tensorflow - 如何在 keras 或 tf.keras 中冻结选定的权重?
- ios - 从 Contentful 获取数据时切换 contentTypeId