英文:
Why am I getting a 'no such file or directory' error when importing images in tkinter using nuitka in Python?
问题
I am developing a tool in python with tkinter.
The structure of my project is the following:
- project folder:
- src
- main.py
- ...other files.py
- changelog.md
- res
- img
- images used by my project
- img
- src
In my main code I import several images in the following way:
question_icon = PhotoImage(file = "../res/img/question_icon_32.png")
When I try to build a one file executable with nuitka, if I execute it the \src folder then everything works, but if I try to move it to some other folder then I get this error when importing the images:
couldn't open "../res/img/question_icon_32.png": no such file or directory.
I figure the problem is the way I import the images, but I wasn't able to understand exactly what am I doing wrong.
I have python 3.11 and nuitka 1.5.8
I call nuitka with:
python -m nuitka --onefile --onefile-tempdir-spec="%TEMP%\onefile_%PID%_%TIME%" -o myprogram.exe --enable-plugin=tk-inter --include-data-dir="C:\...project_folder\res"=res --include-data-file="C:\...project_folder\src\changelog.md"=changelog.md C:\...project_folder\src\main.py
of course "C:...project_folder" is the full absolute path to the project folder.
Do you have any suggestion what am I doing wrong?
I thought the "../" was problematic so I tried putting the \res folder inside the \src folder and change the import to question_icon = PhotoImage(file = "/res/img/question_icon_32.png")
but I still get the same error.
英文:
I am developing a tool in python with tkinter.
The structure of my project is the following:
- project folder:
- src
- main.py
- ...other files.py
- changelog.md
- res
- img
- images used by my project
- img
- src
In my main code I import several images in the following way:
question_icon = PhotoImage(file = "../res/img/question_icon_32.png")
When I try to build a one file executable with nuitka, if I execute it the \src folder then everything works, but if I try to move it to some other folder then I get this error when importing the images:
couldn't open "../res/img/question_icon_32.png": no such file or directory.
I figure the problem is the way I import the images, but I wasn't able to understand exactly what am I doing wrong.
I have python 3.11 and nuitka 1.5.8
I call nuitka with:
python -m nuitka --onefile --onefile-tempdir-spec="%TEMP%\onefile_%PID%_%TIME%" -o myprogram.exe --enable-plugin=tk-inter --include-data-dir="C:\...project_folder\res"=res --include-data-file="C:\...project_folder\src\changelog.md"=changelog.md C:\...project_folder\src\main.py
of course "C:...project_folder" is the full absolute path to the project folder.
Do you have any suggestion what am I doing wrong?
I thought the "../" was problematic so I tried putting the \res folder inside the \src folder and change the import to question_icon = PhotoImage(file = "/res/img/question_icon_32.png")
but I still get the same error
答案1
得分: 1
Nuitka 在主文件和被主文件包含的文件中处理相对导入的方式不同。我通过创建一个包装 .py 文件来解决这个问题,该文件只是调用我的主 .py 文件。然后,我的原始主函数中的所有相对路径都正常工作了。
更新:我已经了解到,Nuitka 处理与 .py 文件的相对路径与处理其他文件(如txt或其他数据文件,您的代码调用的文件)的方式不同。包装函数的解决方法可以解决 .py 文件的问题。当使用 --standalone 和非 .py 文件时,路径需要硬编码为 .dist 文件夹中的位置。(您还需要使用 --include 或复制文件到 .dist 文件夹中)。
英文:
Nuitka handles relative imports differently in the main file vs the files that get included by the main file. I've gotten around this by creating a wrapper .py that just calls my main .py. Then all my relative paths in my original main function worked properly.
Update: I've learned that Nuitka handles relative paths to .py files differently than for other files (such as txt or other data files that your code calls). The wrapper function hack fixes the problem for .py files. When using --standalone and non-py files, the paths need to be hard coded to the location in the .dist folder. (You also need to use --include or copy the files to the .dist folder.)
答案2
得分: 0
以下是您要翻译的内容:
当执行单个可执行文件时,它将在 nuitka 命令中指定的临时文件夹中运行,其中包括 nuitka 中包含的所有资源。我的问题是,此文件夹不尊重我的项目文件夹的相同结构,因此我需要修复导入资源的路径。
最终,我通过以下方式导入资源解决了问题:
question_icon = PhotoImage(file=resource_path("..\\res\\img\\question_icon_32.png"))
其中
def resource_path(relative_path):
# 从相对路径中删除前缀..\。
temp_folder_path_file = os.path.join(os.path.dirname(__file__), relative_path[3:])
if os.path.isfile(temp_folder_path_file):
return temp_folder_path_file
else:
return os.path.join(os.path.abspath('.'), relative_path)
请注意,我已经删除了 HTML 实体编码(如")以使代码更清晰。
英文:
When the single-file executable is executed, it will run in a temp folder specified in the nuitka command, which will include all the resourced included in nuitka. My problem was that this folder do not respect the same structure of my project folder, therefore I needed to fix the path to import the resources.
I eventually solved by importing the resources like this:
question_icon = PhotoImage(file = resource_path("..\\res\\img\\question_icon_32.png"))
where
enter code here
def resource_path(relative_path):
# The prefix ..\ is removed from the relative path
temp_folder_path_file = os.path.join(os.path.dirname(__file__), relative_path[3:])
if os.path.isfile(temp_folder_path_file):
return temp_folder_path_file
else:
return os.path.join(os.path.abspath('.'), relative_path)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论