首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用pyinstaller打包的应用程序不要从临时目录打开文件(tkinter,tksvg,tempfile)

用pyinstaller打包的应用程序不要从临时目录打开文件(tkinter,tksvg,tempfile)
EN

Stack Overflow用户
提问于 2022-10-24 13:43:13
回答 2查看 76关注 0票数 0

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

代码语言:javascript
运行
复制
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()

编辑

在与主题进行了一番斗争之后,我确信这肯定是一个关于pyinstaller如何打包库(特别是tksvg )的问题。@JRiggles提出的方法本身可以工作,但不适用于tksvg对象,在我的示例中也没有必要(我使用临时目录来管理文件)。为了检查临时目录在打包时是否也能工作(pyinstaller),我创建了"jpeg查看器“脚本,它运行良好,甚至使用PIL库。

代码语言:javascript
运行
复制
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。和他们在一起?

EN

Stack Overflow用户

发布于 2022-10-24 13:55:44

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

代码语言:javascript
运行
复制
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)

在您的例子中,您可以这样使用它:

代码语言:javascript
运行
复制
svg_path = fetch_resource(r'path\to\test.svg')
with open(svg_path, 'w') as a_file:
...
svg_image = tksvg.SvgImage(file=svg_path)

您需要通过使用--add-data命令行或将路径添加到*.spec文件中的datas列表中,告诉pyinstaller在哪里查找要“获取”的任何文件。

票数 1
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74182018

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档