使用 pyinstaller 打包的应用程序不会从临时目录(tkinter、tksvg、tempfile)中打开文件

2023-12-27

大家好,我对一个包含 pyinstaller 的简单应用程序(至少 MRE 很简单)有疑问。 这个桌面应用程序应该显示一个简单的 SVG 文件(我使用 tksvg)。 我的应用程序首先将 SVG 写入临时目录(写入不像 MRE 那样简单),然后在适当的时候显示它。它工作得很好,直到我用 pyinstaller 打包它。 我的完整应用程序控制台向我抛出无法找到该文件的错误。该路径始终以 \tksvg 结尾。并且这样的目录不存在。 看起来 tksvg 会创建这样的子文件夹,但 pyinstaller 缺少这样的指令? 我能做什么有什么想法吗? 警告,完全菜鸟。 谢谢

from tkinter import *
import tempfile
import tksvg

root = Tk()

temp_dir = tempfile.TemporaryDirectory()
print(temp_dir.name)
with open(temp_dir.name + f'\\test.svg', 'w') as a_file:
    a_file.write('<svg viewBox="0 0 400 400"><rect x="0" y="0" width="400" height="400"    fill="red" /></svg>')

svg_image = tksvg.SvgImage(file=temp_dir.name + f'\\test.svg')
show_svg = Label(root, image=svg_image)
show_svg.pack()


mainloop()

Edit

经过一番与该主题的斗争后,我确信这一定是 pyinstaller 如何打包库(特别是 tksvg)的问题。 @JRiggles 提出的方法本身有效,但不适用于 tksvg 对象,并且在我的情况下没有必要(我使用临时目录来管理文件)。 为了检查临时目录在打包(pyinstaller)时是否也能正常工作,我创建了“jpeg reader”脚本,即使使用 PIL 库,它也能完美工作。

from tkinter import *
import tempfile
from tkinter import filedialog
from PIL import Image, ImageTk

root = Tk()


temp_dir = tempfile.TemporaryDirectory()
print(temp_dir.name)  # just to check if temp. dir. was created

jpeg_file = filedialog.askopenfilename(filetypes=[("jpeg file", "*.jpeg")])  # opening file from disc
picture = Image.open(jpeg_file)  # reading it with PIL library
picture.save(temp_dir.name+'\\test.jpeg')  # saving image to temp. dir.

an_image = Image.open(temp_dir.name + '\\test.jpeg')  # opening image from temp.dir.
the_image = ImageTk.PhotoImage(an_image)  # reading image

show_image = Label(root, image=the_image)  # setting label as "display"
show_image.pack()  # showing the image


mainloop()

有没有人有 SVG 库、tksvg 或任何其他库的经验,以及如何制作 exe。跟他们?


Pyinstaller 将您的资源(图像、图标等)放置在运行时在临时目录中创建的特殊目录中。我用这个fetch_resource运行 pyinstaller 可执行文件时动态加载资源的函数

import sys
from pathlib import Path


def fetch_resource(rsrc_path):
    """Loads resources from the temp dir used by pyinstaller executables"""
    try:
        base_path = Path(sys._MEIPASS)
    except AttributeError:
        return rsrc_path  # not running as exe, just return the unaltered path
    else:
        return base_path.joinpath(rsrc_path)

在你的情况下,你会像这样使用它:

svg_path = fetch_resource(r'path\to\test.svg')
with open(svg_path, 'w') as a_file:
...
svg_image = tksvg.SvgImage(file=svg_path)

您需要告诉 pyinstaller 在哪里找到您想要“获取”的任何文件,方法是使用--add-data命令行or通过添加路径datas列出您的*.spec file

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 pyinstaller 打包的应用程序不会从临时目录(tkinter、tksvg、tempfile)中打开文件 的相关文章

随机推荐