python GUI 中的 pyinstaller 捆绑图像到一个文件 EXE?
python pyinstaller bundle image in GUI to onefile EXE?
我已经从 python tkinter GUI 成功创建了一个包含图像的 EXE 文件。见以下代码:
lblLogo=Label(main)
lblLogo.grid(row=3,column=11,rowspan=4)
try:
filelocation="C:/Documents/Python/ScreenPartNumberProgram/"
KasonLogo=PhotoImage(file=filelocation+"KasonLogo.png")
KasonLogo=KasonLogo.zoom(25,20)
KasonLogo=KasonLogo.subsample(50,50)
lblLogo.config(image=KasonLogo)
icon=PhotoImage(file=filelocation+"KasonLogo.png")
main.tk.call('wm','iconphoto',main._w,icon)
except:
print("warning: could not load photos")
lblLogo.config(text="[KasonLogo.png]")
exe 文件在我的电脑上打开并完美运行。我使用此命令获取 .exe:
pyinstaller --onefile --noconsole myscript.py
唯一的问题是此文件要求图像位于同一文件夹中,否则它不会显示在标签上。如何在不需要外部文件的情况下将图像捆绑到 EXE 中?
提前致谢
编辑:
我查看了提供的链接,进行了更多研究,但仍未解决问题。该程序仅在图像位于同一文件夹中时才有效。我真的很想让它在不需要外部图像文件的情况下工作。 resource_path 技术似乎也不适合我...
我也尝试修改我的代码以使用 PIL 的 ImageTk 和同样的问题。仅当外部图像文件位于包含它的文件夹中时,程序才会加载图像。
天哪!经过几天的头痛之后,我终于找到了一种可行的方法......这是我在不需要外部图像文件的情况下使程序运行的方法:
第一步:对图片文件进行编码(注意必须是GIF,可以使用paint转换):
import base64
with open("MyPicture.gif", "rb") as image_file:
encoded_string = base64.b64encode(image_file.read())
print(encoded_string)#print string to copy it (see step 2)
第 2 步:下一步是将字符串复制并粘贴到单独的 myimages.py 文件中,然后
将其存储为变量。例如:
imageString = b'R0lGODlhyADIAPcAAAA .....blah blah really long string.......'
第三步:然后将myimages.py导入主程序,调用变量
from myimages import *
pic=imageString#GIF decoded to string. imageString from myimages.py
render = PhotoImage(data=pic)
myLabel.config(image=render)
第 4 步:在规范文件中:包含 myimages.py 作为数据
# -*- mode: python -*-
block_cipher = None
#instructions: pyinstaller --onefile --noconsole myProgram.spec
file_name = 'myProgram'
add_files=[('myimages.py','module')]
a = Analysis([file_name+'.py'],
pathex=['C:\Program Files (x86)\Python36-32\Scripts'],
binaries=[],
datas=add_files,
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=exclude_list,
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
name=file_name,
debug=False,
strip=False,
upx=True,
runtime_tmpdir=None,
console=False )
第五步:终于可以编译成EXE了:
pyinstaller --onefile --noconsole myProgram.spec
SIGH 如果有人有更好的解决方案,请post 在这里。在那之前我很高兴有些东西能用...
当我想包含一个 .ico 文件用作我的 tkinter 应用程序的图标时,我 运行 遇到了同样的问题。这是我如何让它工作的:
在使用 PyInstaller 构建 .exe 文件时,我指定了 --add-data 选项以及我的 .ico 的完整路径。
应用程序启动时,它必须从临时目录中的 .exe 解压所有内容,因此我获取该临时目录的路径并使用它来指定我的 . ico文件。
在启动主循环之前,使用 'tempfile' 获取临时文件目录并使用 'glob' 检查文件模式匹配:
tempdir = tempfile.gettempdir()
icon_path = tempdir + '\' + 'next_subdirectory_pattern' + '\' + '*.ico'
icon_matches = glob.glob(icon_path)
if len(icon_matches) > 0:
logo = icon_matches[0]
else:
logo = ''
tk.Tk.iconbitmap(self, default=logo)
可能不是最 eloquent 的方法,但它确实有效。
我是这样做的...
将图像与可执行文件捆绑在一起:
使用以下命令将您的图标保存到名为“icon”的文件夹中,该文件夹将在运行时由 pyinstaller 生成的“C:\Users<用户名>\AppData\Local\Temp_MEI123456”文件夹中生成:
--add-data=C:\absolute\path\to\your\ICON.ico;icon
我的完整命令行,我在 python 终端中输入的字符串(我正在使用 pycharm IDE)生成我的 EXE,如下所示:
pyinstaller -w -F -i=C:\absolute\path\to\your\ICON.ico --add-data=C:\absolute\path\to\your\ICON.ico;icon -n=MyEXEsNameV1 main.py
(对于调试,省略 -w 并添加 --debug=all 很有帮助)
文档参考:https://pyinstaller.readthedocs.io/en/stable/usage.html#options-group-what-to-bundle-where-to-search
在我的 python 脚本中访问图像 main.py:
我使用以下代码设置 tk window:
import tkinter as tk
from os import path
# main widget
self.root = tk.Tk(master)
self.root.title('Window Title Bar Name V1.0')
self.root.minsize(1234, 1234)
# get icon
try:
# Get the absolute path of the temp directory
path_to_icon = path.abspath(path.join(path.dirname(__file__), 'icon/GAUGE-ICON.ico'))
# set the icon of the tk window
self.root.iconbitmap(path_to_icon)
except:
pass
文档参考:https://pyinstaller.readthedocs.io/en/stable/runtime-information.html
除了接受的答案我想添加修改版本:
from PIL import Image, ImageTk
from res import *
#res is a module with your base64 image string and in my case variable is icon_base64
from base64 import b64decode
pic_as_bytes=ImageTk.BytesIO(icon_base64)
my_image=Image.open(pic_as_bytes)
请注意此代码可以在 Python3 中使用,但不能在 Python2 中使用,因为它需要不同的方法和更多的转换(下面的 link 有一个 Python2).
更多信息请参考https://github.com/Ariel-MN/Tkinter_base64_Images/blob/master/tkinter_base64_image-ico.py
我尝试了以下方法。第二个选项对我有用。
使用你说的命令生成exe文件,将exe文件复制到你项目的源文件夹中(python文件所在的文件夹)
我使用 auto-py-to-exe 修复它,它使用 pyinstaller。给你
可以看到生成的命令。
pyinstaller --noconfirm --onedir --windowed --add-data "path/assets/" "path/gui.py"
首先,尝试使用 --onefile
而不是 --onedir
。我的没用
当我使用 --onefile
时。所以只好隐蔽--onedir
.
我已经从 python tkinter GUI 成功创建了一个包含图像的 EXE 文件。见以下代码:
lblLogo=Label(main)
lblLogo.grid(row=3,column=11,rowspan=4)
try:
filelocation="C:/Documents/Python/ScreenPartNumberProgram/"
KasonLogo=PhotoImage(file=filelocation+"KasonLogo.png")
KasonLogo=KasonLogo.zoom(25,20)
KasonLogo=KasonLogo.subsample(50,50)
lblLogo.config(image=KasonLogo)
icon=PhotoImage(file=filelocation+"KasonLogo.png")
main.tk.call('wm','iconphoto',main._w,icon)
except:
print("warning: could not load photos")
lblLogo.config(text="[KasonLogo.png]")
exe 文件在我的电脑上打开并完美运行。我使用此命令获取 .exe:
pyinstaller --onefile --noconsole myscript.py
唯一的问题是此文件要求图像位于同一文件夹中,否则它不会显示在标签上。如何在不需要外部文件的情况下将图像捆绑到 EXE 中?
提前致谢
编辑: 我查看了提供的链接,进行了更多研究,但仍未解决问题。该程序仅在图像位于同一文件夹中时才有效。我真的很想让它在不需要外部图像文件的情况下工作。 resource_path 技术似乎也不适合我...
我也尝试修改我的代码以使用 PIL 的 ImageTk 和同样的问题。仅当外部图像文件位于包含它的文件夹中时,程序才会加载图像。
天哪!经过几天的头痛之后,我终于找到了一种可行的方法......这是我在不需要外部图像文件的情况下使程序运行的方法:
第一步:对图片文件进行编码(注意必须是GIF,可以使用paint转换):
import base64
with open("MyPicture.gif", "rb") as image_file:
encoded_string = base64.b64encode(image_file.read())
print(encoded_string)#print string to copy it (see step 2)
第 2 步:下一步是将字符串复制并粘贴到单独的 myimages.py 文件中,然后 将其存储为变量。例如:
imageString = b'R0lGODlhyADIAPcAAAA .....blah blah really long string.......'
第三步:然后将myimages.py导入主程序,调用变量
from myimages import *
pic=imageString#GIF decoded to string. imageString from myimages.py
render = PhotoImage(data=pic)
myLabel.config(image=render)
第 4 步:在规范文件中:包含 myimages.py 作为数据
# -*- mode: python -*-
block_cipher = None
#instructions: pyinstaller --onefile --noconsole myProgram.spec
file_name = 'myProgram'
add_files=[('myimages.py','module')]
a = Analysis([file_name+'.py'],
pathex=['C:\Program Files (x86)\Python36-32\Scripts'],
binaries=[],
datas=add_files,
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=exclude_list,
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
name=file_name,
debug=False,
strip=False,
upx=True,
runtime_tmpdir=None,
console=False )
第五步:终于可以编译成EXE了:
pyinstaller --onefile --noconsole myProgram.spec
SIGH 如果有人有更好的解决方案,请post 在这里。在那之前我很高兴有些东西能用...
当我想包含一个 .ico 文件用作我的 tkinter 应用程序的图标时,我 运行 遇到了同样的问题。这是我如何让它工作的:
在使用 PyInstaller 构建 .exe 文件时,我指定了 --add-data 选项以及我的 .ico 的完整路径。
应用程序启动时,它必须从临时目录中的 .exe 解压所有内容,因此我获取该临时目录的路径并使用它来指定我的 . ico文件。
在启动主循环之前,使用 'tempfile' 获取临时文件目录并使用 'glob' 检查文件模式匹配:
tempdir = tempfile.gettempdir()
icon_path = tempdir + '\' + 'next_subdirectory_pattern' + '\' + '*.ico'
icon_matches = glob.glob(icon_path)
if len(icon_matches) > 0:
logo = icon_matches[0]
else:
logo = ''
tk.Tk.iconbitmap(self, default=logo)
可能不是最 eloquent 的方法,但它确实有效。
我是这样做的...
将图像与可执行文件捆绑在一起:
使用以下命令将您的图标保存到名为“icon”的文件夹中,该文件夹将在运行时由 pyinstaller 生成的“C:\Users<用户名>\AppData\Local\Temp_MEI123456”文件夹中生成:
--add-data=C:\absolute\path\to\your\ICON.ico;icon
我的完整命令行,我在 python 终端中输入的字符串(我正在使用 pycharm IDE)生成我的 EXE,如下所示:
pyinstaller -w -F -i=C:\absolute\path\to\your\ICON.ico --add-data=C:\absolute\path\to\your\ICON.ico;icon -n=MyEXEsNameV1 main.py
(对于调试,省略 -w 并添加 --debug=all 很有帮助)
文档参考:https://pyinstaller.readthedocs.io/en/stable/usage.html#options-group-what-to-bundle-where-to-search
在我的 python 脚本中访问图像 main.py:
我使用以下代码设置 tk window:
import tkinter as tk
from os import path
# main widget
self.root = tk.Tk(master)
self.root.title('Window Title Bar Name V1.0')
self.root.minsize(1234, 1234)
# get icon
try:
# Get the absolute path of the temp directory
path_to_icon = path.abspath(path.join(path.dirname(__file__), 'icon/GAUGE-ICON.ico'))
# set the icon of the tk window
self.root.iconbitmap(path_to_icon)
except:
pass
文档参考:https://pyinstaller.readthedocs.io/en/stable/runtime-information.html
除了接受的答案我想添加修改版本:
from PIL import Image, ImageTk
from res import *
#res is a module with your base64 image string and in my case variable is icon_base64
from base64 import b64decode
pic_as_bytes=ImageTk.BytesIO(icon_base64)
my_image=Image.open(pic_as_bytes)
请注意此代码可以在 Python3 中使用,但不能在 Python2 中使用,因为它需要不同的方法和更多的转换(下面的 link 有一个 Python2).
更多信息请参考https://github.com/Ariel-MN/Tkinter_base64_Images/blob/master/tkinter_base64_image-ico.py
我尝试了以下方法。第二个选项对我有用。
使用你说的命令生成exe文件,将exe文件复制到你项目的源文件夹中(python文件所在的文件夹)
我使用 auto-py-to-exe 修复它,它使用 pyinstaller。给你 可以看到生成的命令。
pyinstaller --noconfirm --onedir --windowed --add-data "path/assets/" "path/gui.py"
首先,尝试使用
--onefile
而不是--onedir
。我的没用 当我使用--onefile
时。所以只好隐蔽--onedir
.