[英]python - unable to add image to the GUI(tkinter) on windows
我正在使用python(我的版本是2.7
)。 我想将图像添加到GUI( Tkinter
),然后使用pyinstaller
转换为可执行格式。 我按照SO以及ActiveState的说明进行了跟踪
当我在代码中提及图片的路径时,仅当我直接运行它时它才起作用。 如果我将其转换为exe
,它将无法打开。
如其他解决方案所述更改代码,例如通过将其转换为编码的字符串,它可以在linux上正常运行。 但是在Windows上会引发错误
码:
from Tkinter import *
from PIL import ImageTk, Image
logo = '''
----- encoded string -----
'''
root = Tk()
logoimage = Tkinter.PhotoImage(master=root, data=logo)
Label(root, image=logoimage).pack()
root.mainloop()
变更1:以上代码在Linux上有效。 在Windows上,我在行logoimage = Tkinter.PhotoImage(master=root, data=logo)
出错
NameError: name 'Tkinter' is not defined
更改2:所以我尝试将行更改为logoimage = ImageTk.PhotoImage(master=root, data=logo)
。 我得到的错误是
File "C:\Python27\lib\site-packages\PIL\ImageTk.py", line 88, in __init__
image = Image.open(BytesIO(kw["data"]))
File "C:\Python27\lib\site-packages\PIL\Image.py", line 2330, in open
% (filename if filename else fp))
IOError: cannot identify image file <_io.BytesIO object at 0x00000000024BB150>
Exception AttributeError: "'PhotoImage' object has no attribute '_PhotoImage__photo'" in <bound method PhotoImage.__del__ of <PIL.ImageTk.PhotoImage object at 0x00000000024D49E8>> ignored
更改3:但是,如果我将行更改为iconImage= ImageTk.PhotoImage(Image.open('path_to_image.png'))
。 仅当我直接运行时它才有效。 如果我将其转换为可执行文件,则控制台将打开2-3秒,并显示诸如Unable to locate the image file
类的错误
显式地进行解码和转换可能比您当前正在执行的功能更强大。 该代码在Linux上的Python 2.6.6上有效。
import io, base64
from Tkinter import *
from PIL import ImageTk, Image
#A simple 64x64 PNG fading from orange in the top left corner
# to red in the bottom right, encoded in base64
logo_b64 = '''
iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAIA
AAAlC+aJAAAA/0lEQVR4nO3Zyw7CMAxEUdP//+W2rCqBoJA2noclS1kn9yjLeex7xKY76+
wNS+l6KSCjXgdIqhcB8uoVgNR6OiC7ngsA1BMBmHoWAFZPASDr8QBwPRiAr0cCKPUwAKse
AyDWAwDc+mwAvT4VoKjPA4jqkwC6+gyAtD7WSYC6fu4HDOonAB71dwE29bcATvXXAWb1Fw
F+9VcAlvXDANf6MYBx/QDAu/4fwL7+J6BC/TmgSP0JoE79N0Cp+g9Atfp3QMH6F0DN+gNQ
tj62WErXB2PgQNZLAb3U6wC91OsAvdTrAL3U6wC91OsAvdTrAL3U6wC91OsAvdTrAL3Uz7
z+BNmX4gqbppsaAAAAAElFTkSuQmCC
'''
#Decode the PNG data & "wrap" it into a file-like object
fh = io.BytesIO(base64.b64decode(logo_b64))
#Create a PIL image from the PNG data
img = Image.open(fh, mode='r')
#We must open the window before calling ImageTk.PhotoImage
root = Tk()
photo = ImageTk.PhotoImage(image=img)
Label(root, image=photo).pack()
Label(root, text='An embedded\nbase64-encoded PNG').pack()
root.mainloop()
供参考,这是嵌入式PNG的外观。
from Tkinter import *
#...
logoimage = Tkinter.PhotoImage(master=root, data=logo)
如果使用import *
将Tkinter模块直接转储到全局范围中,则不应在模块名称和类名和函数名之间添加前缀。 删除前缀,或删除import *
。
import Tkinter
#...
logoimage = Tkinter.PhotoImage(master=root, data=logo)
要么
from Tkinter import *
#...
logoimage = PhotoImage(master=root, data=logo)
我怀疑您在Linux中没有收到错误消息,因为您的Python版本会自动导入通用模块。 实际上,所有脚本的顶部都有一个不可见的import Tkinter
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.