首页 > 解决方案 > 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 文件。

标签: pythonkivypyinstaller

解决方案


几个小时后,我终于明白了。我首先打开我的 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', '.')],

推荐阅读