Python Tkinter .jpeg 图像未显示 -- TclError
Python Tkinter .jpeg Image not displaying -- TclError
我正在尝试向我的 GUI 添加一个 .jpeg
图像,而它还有其他几个小部件。
使用我的代码,当我使用以下命令时,我可以在单独的 Tkinter
window 中显示图像:
#self.label = Label(image = self.img)
但是,每当我尝试将图像添加到原始 Tkinter
window 时,我都会在代码下方看到错误。我尝试将其添加到原始 Tkinter window 的方式是:
#self.label = Label(frame, image = self.img)
重现错误
奇怪的是,当我尝试在较短版本的代码(例如下面的代码)中复制错误时,它起作用了。然而!要在缩短的代码中复制错误,您需要先创建一个不同的错误。示例:将 text = "Try"
替换为 text = "%s" %yikes
(因为没有变量 yikes
会报错)。将代码改回之前的确切方式后,它会产生我在下面描述的错误 (TclError: image "pyimage__" doesn't exit
)。在最底部,我包含了整个 class,因为我很难始终如一地复制问题。我正在使用 Python 2.7 和 Canopy 1.5.5。
缩短代码:
import matplotlib.pyplot as plt
from Tkinter import *
from PIL import ImageTk, Image
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import numpy as np
from tkFileDialog import askopenfilename, askdirectory
class App:
def __init__(self, master):
frame = Frame(master)
self.button_left = Button(frame,text="< Previous Event")
self.button_left.grid(row=1,column=0)
self.button_right = Button(frame,text="Next Event >")
self.button_right.grid(row=1,column=3)
#Creating text for the UI indicating the number of leakage events
w = Label(frame, text="Trying to Recreate error")
w.grid(row=1,column=2)
self.m = Canvas(frame,width=50,height=25)
self.text_id = self.m.create_text(25,12.5, text="Try")
self.m.grid(row=1,column=1)
self.path = "C:\Carbonite\EL_36604.02_231694\EL_36604.02_231694_2015-06-15 10.39.57.jpeg"
self.image = Image.open(self.path)
self.img = ImageTk.PhotoImage(self.image)
#self.label = Label(image = self.img)
self.label = Label(frame,image = self.img)
self.label.image = self.img
self.label.grid(row = 3, column = 0)
frame.grid(row=0,column=0)
root = Tk()
app = App(root)
root.mainloop()
当我使用注释掉的方法时我的程序收到错误:
TclError Traceback (most recent call last)
C:\Carbonite\Main_interface_file.py in <module>()
136
137 root = Tk()
--> 138 app = App(root)
139 root.mainloop()
140
C:\Carbonite\Main_interface_file.py in __init__(self, master)
72 self.img = ImageTk.PhotoImage(self.image)
73 #self.label = Label(image = self.img)
---> 74 self.label = Label(frame,image = self.img)
75 self.label.image = self.img
76 self.label.grid(row=3, column = 0)
C:\Users\U10596\AppData\Local\Enthought\Canopy\App\appdata\canopy-1.5.5.3123.win-x86_64\lib\lib-tk\Tkinter.pyc in __init__(self, master, cnf, **kw)
2585
2586 """
-> 2587 Widget.__init__(self, master, 'label', cnf, kw)
2588
2589 class Listbox(Widget, XView, YView):
C:\Users\U10596\AppData\Local\Enthought\Canopy\App\appdata\canopy-1.5.5.3123.win-x86_64\lib\lib-tk\Tkinter.pyc in __init__(self, master, widgetName, cnf, kw, extra)
2084 del cnf[k]
2085 self.tk.call(
-> 2086 (widgetName, self._w) + extra + self._options(cnf))
2087 for k, v in classes:
2088 k.configure(self, v)
TclError: image "pyimage8" doesn't exist
几乎整个代码:
import matplotlib.pyplot as plt
from Tkinter import *
from PIL import ImageTk, Image
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import numpy as np
from images_to_list import images_to_list
from tkFileDialog import askopenfilename, askdirectory
#Creating a class that creates the UI
class App:
def __init__(self, master):
self.event_num = 1
# Create a container
frame = Frame(master)
# Create 2 buttons (changes between leakage events
self.button_left = Button(frame,text="< Previous Event",
command=self.decrease)
self.button_left.grid(row=1,column=0)
self.button_right = Button(frame,text="Next Event >",
command=self.increase)
self.button_right.grid(row=1,column=3)
#Creating text for the UI indicating the number of leakage events
w = Label(frame, text="/ %s " % len(tft))
w.grid(row=1,column=2)
#Display the number of the current event in the series
self.m = Canvas(frame,width=50,height=25)
self.text_id = self.m.create_text(25,12.5, text="%s" % (self.event_num+1))
self.m.grid(row=1,column=1)
#Creating the plot of voltage data
self.fig = Figure()
self.ax = self.fig.add_subplot(111)
self.fig.autofmt_xdate()
import matplotlib.dates as mdates
self.ax.fmt_xdata = mdates.DateFormatter('%Y-%m-%d')
self.line, = self.ax.plot(tft[self.event_num],tf1[self.event_num],'.')
self.line2, = self.ax.plot(tft[self.event_num],tf2[self.event_num],'.')
self.ax.set_ylim([0,3.5])
self.path = "C:\Carbonite\EL_36604.02_231694\EL_36604.02_231694_2015-06-15 10.39.57.jpeg"
self.image = Image.open(self.path)
self.img = ImageTk.PhotoImage(self.image)
#self.label = Label(image = self.img)
self.label = Label(frame,image = self.img)
self.label.image = self.img
self.label.grid(row=3, column = 0)
self.canvas = FigureCanvasTkAgg(self.fig,master=master)
self.canvas.show()
self.canvas.get_tk_widget().grid(row=1,column=0)
frame.grid(row=0,column=0)
#Creating a textbox to jump to event number
self.textbox = Entry(frame,width=5)
button1 = Button(frame, text='Go', command=self.letsgo) #Linking "Go" button with letsgo function to jump to event number
self.textbox.grid(row=2,column=1)
button1.grid(row=2,column=2)
#function letsgo allows the user to jump to any event in the series
def letsgo(self):
txt = self.textbox.get()
try:
self.event_num = int(txt)
except ValueError:
print "Opps! The number you enter needs to be an integer!"
self.line.set_xdata(tft[self.event_num])
self.line.set_ydata(tf1[self.event_num])
self.line2.set_xdata(tft[self.event_num])
self.line2.set_ydata(tf2[self.event_num])
self.ax.set_xlim([min(tft[self.event_num]),max(tft[self.event_num])])
self.canvas.draw()
self.m.itemconfig(self.text_id, text="%s" % (self.event_num+1))
#function decrease allows the user to use the decrease button
def decrease(self):
if self.event_num == 0: #if statement accounts for if the user tries to see the event previous to the first one
self.event_num = len(tft)-1
else:
self.event_num -= 1
self.line.set_xdata(tft[self.event_num])
self.line.set_ydata(tf1[self.event_num])
self.line2.set_xdata(tft[self.event_num])
self.line2.set_ydata(tf2[self.event_num])
self.ax.set_xlim([min(tft[self.event_num]),max(tft[self.event_num])])
self.canvas.draw()
self.m.itemconfig(self.text_id, text="%s" % (self.event_num+1))
#function increase allows the user to use the increase button
def increase(self):
if self.event_num == len(tft)-1: #if statement accounts for if the user tries to see the event after the last one.
self.event_num = 0
else:
self.event_num += 1
self.line.set_xdata(tft[self.event_num])
self.line.set_ydata(tf1[self.event_num])
self.line2.set_xdata(tft[self.event_num])
self.line2.set_ydata(tf2[self.event_num])
self.ax.set_xlim([min(tft[self.event_num]),max(tft[self.event_num])])
self.canvas.draw()
self.m.itemconfig(self.text_id, text="%s" % (self.event_num+1))
root = Tk()
app = App(root)
root.mainloop()
您需要对框架进行网格化。当我添加
frame.grid()
在您的 __init__
方法的底部,它工作正常。不过,当我 运行 您发布的代码时,我没有收到错误消息。它只是不显示标签。我想知道这是否是某种依赖于平台的行为。我在 Yosemite 10.10.5 上使用 python 2.7。
编辑:我试过你的扩展示例,正如预期的那样,我没有看到你的行为。我可以来回更改代码。当它不正确时,我得到一个错误;当它正确时,它 运行 没问题。
你描述的行为肯定与 Canopy 有关。 python 解释器的工作方式,它会在每次 运行s 时将脚本编译为字节码;它对脚本过去所说的内容一无所知。
您可以尝试从命令行 运行 运行可疑脚本吗?另外,也许您应该将 canopy
标记添加到您的问题中。
我不使用 Canopy,所以我认为我无法为您提供帮助,但我将答案留在这里作为背景,以供有希望的人使用。
祝你好运。
我找到问题了!!
我在代码的最开始使用了 askopenfilename()
,它打开了一个额外的 Tkinter
window。结果有两个Tkinter
windows打开了程序,把程序搞糊涂了。
通过将所有内容发送到创建的第一个 Tk
window(并删除第二个),它解决了问题。
我正在尝试向我的 GUI 添加一个 .jpeg
图像,而它还有其他几个小部件。
使用我的代码,当我使用以下命令时,我可以在单独的 Tkinter
window 中显示图像:
#self.label = Label(image = self.img)
但是,每当我尝试将图像添加到原始 Tkinter
window 时,我都会在代码下方看到错误。我尝试将其添加到原始 Tkinter window 的方式是:
#self.label = Label(frame, image = self.img)
重现错误
奇怪的是,当我尝试在较短版本的代码(例如下面的代码)中复制错误时,它起作用了。然而!要在缩短的代码中复制错误,您需要先创建一个不同的错误。示例:将 text = "Try"
替换为 text = "%s" %yikes
(因为没有变量 yikes
会报错)。将代码改回之前的确切方式后,它会产生我在下面描述的错误 (TclError: image "pyimage__" doesn't exit
)。在最底部,我包含了整个 class,因为我很难始终如一地复制问题。我正在使用 Python 2.7 和 Canopy 1.5.5。
缩短代码:
import matplotlib.pyplot as plt
from Tkinter import *
from PIL import ImageTk, Image
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import numpy as np
from tkFileDialog import askopenfilename, askdirectory
class App:
def __init__(self, master):
frame = Frame(master)
self.button_left = Button(frame,text="< Previous Event")
self.button_left.grid(row=1,column=0)
self.button_right = Button(frame,text="Next Event >")
self.button_right.grid(row=1,column=3)
#Creating text for the UI indicating the number of leakage events
w = Label(frame, text="Trying to Recreate error")
w.grid(row=1,column=2)
self.m = Canvas(frame,width=50,height=25)
self.text_id = self.m.create_text(25,12.5, text="Try")
self.m.grid(row=1,column=1)
self.path = "C:\Carbonite\EL_36604.02_231694\EL_36604.02_231694_2015-06-15 10.39.57.jpeg"
self.image = Image.open(self.path)
self.img = ImageTk.PhotoImage(self.image)
#self.label = Label(image = self.img)
self.label = Label(frame,image = self.img)
self.label.image = self.img
self.label.grid(row = 3, column = 0)
frame.grid(row=0,column=0)
root = Tk()
app = App(root)
root.mainloop()
当我使用注释掉的方法时我的程序收到错误:
TclError Traceback (most recent call last)
C:\Carbonite\Main_interface_file.py in <module>()
136
137 root = Tk()
--> 138 app = App(root)
139 root.mainloop()
140
C:\Carbonite\Main_interface_file.py in __init__(self, master)
72 self.img = ImageTk.PhotoImage(self.image)
73 #self.label = Label(image = self.img)
---> 74 self.label = Label(frame,image = self.img)
75 self.label.image = self.img
76 self.label.grid(row=3, column = 0)
C:\Users\U10596\AppData\Local\Enthought\Canopy\App\appdata\canopy-1.5.5.3123.win-x86_64\lib\lib-tk\Tkinter.pyc in __init__(self, master, cnf, **kw)
2585
2586 """
-> 2587 Widget.__init__(self, master, 'label', cnf, kw)
2588
2589 class Listbox(Widget, XView, YView):
C:\Users\U10596\AppData\Local\Enthought\Canopy\App\appdata\canopy-1.5.5.3123.win-x86_64\lib\lib-tk\Tkinter.pyc in __init__(self, master, widgetName, cnf, kw, extra)
2084 del cnf[k]
2085 self.tk.call(
-> 2086 (widgetName, self._w) + extra + self._options(cnf))
2087 for k, v in classes:
2088 k.configure(self, v)
TclError: image "pyimage8" doesn't exist
几乎整个代码:
import matplotlib.pyplot as plt
from Tkinter import *
from PIL import ImageTk, Image
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import numpy as np
from images_to_list import images_to_list
from tkFileDialog import askopenfilename, askdirectory
#Creating a class that creates the UI
class App:
def __init__(self, master):
self.event_num = 1
# Create a container
frame = Frame(master)
# Create 2 buttons (changes between leakage events
self.button_left = Button(frame,text="< Previous Event",
command=self.decrease)
self.button_left.grid(row=1,column=0)
self.button_right = Button(frame,text="Next Event >",
command=self.increase)
self.button_right.grid(row=1,column=3)
#Creating text for the UI indicating the number of leakage events
w = Label(frame, text="/ %s " % len(tft))
w.grid(row=1,column=2)
#Display the number of the current event in the series
self.m = Canvas(frame,width=50,height=25)
self.text_id = self.m.create_text(25,12.5, text="%s" % (self.event_num+1))
self.m.grid(row=1,column=1)
#Creating the plot of voltage data
self.fig = Figure()
self.ax = self.fig.add_subplot(111)
self.fig.autofmt_xdate()
import matplotlib.dates as mdates
self.ax.fmt_xdata = mdates.DateFormatter('%Y-%m-%d')
self.line, = self.ax.plot(tft[self.event_num],tf1[self.event_num],'.')
self.line2, = self.ax.plot(tft[self.event_num],tf2[self.event_num],'.')
self.ax.set_ylim([0,3.5])
self.path = "C:\Carbonite\EL_36604.02_231694\EL_36604.02_231694_2015-06-15 10.39.57.jpeg"
self.image = Image.open(self.path)
self.img = ImageTk.PhotoImage(self.image)
#self.label = Label(image = self.img)
self.label = Label(frame,image = self.img)
self.label.image = self.img
self.label.grid(row=3, column = 0)
self.canvas = FigureCanvasTkAgg(self.fig,master=master)
self.canvas.show()
self.canvas.get_tk_widget().grid(row=1,column=0)
frame.grid(row=0,column=0)
#Creating a textbox to jump to event number
self.textbox = Entry(frame,width=5)
button1 = Button(frame, text='Go', command=self.letsgo) #Linking "Go" button with letsgo function to jump to event number
self.textbox.grid(row=2,column=1)
button1.grid(row=2,column=2)
#function letsgo allows the user to jump to any event in the series
def letsgo(self):
txt = self.textbox.get()
try:
self.event_num = int(txt)
except ValueError:
print "Opps! The number you enter needs to be an integer!"
self.line.set_xdata(tft[self.event_num])
self.line.set_ydata(tf1[self.event_num])
self.line2.set_xdata(tft[self.event_num])
self.line2.set_ydata(tf2[self.event_num])
self.ax.set_xlim([min(tft[self.event_num]),max(tft[self.event_num])])
self.canvas.draw()
self.m.itemconfig(self.text_id, text="%s" % (self.event_num+1))
#function decrease allows the user to use the decrease button
def decrease(self):
if self.event_num == 0: #if statement accounts for if the user tries to see the event previous to the first one
self.event_num = len(tft)-1
else:
self.event_num -= 1
self.line.set_xdata(tft[self.event_num])
self.line.set_ydata(tf1[self.event_num])
self.line2.set_xdata(tft[self.event_num])
self.line2.set_ydata(tf2[self.event_num])
self.ax.set_xlim([min(tft[self.event_num]),max(tft[self.event_num])])
self.canvas.draw()
self.m.itemconfig(self.text_id, text="%s" % (self.event_num+1))
#function increase allows the user to use the increase button
def increase(self):
if self.event_num == len(tft)-1: #if statement accounts for if the user tries to see the event after the last one.
self.event_num = 0
else:
self.event_num += 1
self.line.set_xdata(tft[self.event_num])
self.line.set_ydata(tf1[self.event_num])
self.line2.set_xdata(tft[self.event_num])
self.line2.set_ydata(tf2[self.event_num])
self.ax.set_xlim([min(tft[self.event_num]),max(tft[self.event_num])])
self.canvas.draw()
self.m.itemconfig(self.text_id, text="%s" % (self.event_num+1))
root = Tk()
app = App(root)
root.mainloop()
您需要对框架进行网格化。当我添加
frame.grid()
在您的 __init__
方法的底部,它工作正常。不过,当我 运行 您发布的代码时,我没有收到错误消息。它只是不显示标签。我想知道这是否是某种依赖于平台的行为。我在 Yosemite 10.10.5 上使用 python 2.7。
编辑:我试过你的扩展示例,正如预期的那样,我没有看到你的行为。我可以来回更改代码。当它不正确时,我得到一个错误;当它正确时,它 运行 没问题。
你描述的行为肯定与 Canopy 有关。 python 解释器的工作方式,它会在每次 运行s 时将脚本编译为字节码;它对脚本过去所说的内容一无所知。
您可以尝试从命令行 运行 运行可疑脚本吗?另外,也许您应该将 canopy
标记添加到您的问题中。
我不使用 Canopy,所以我认为我无法为您提供帮助,但我将答案留在这里作为背景,以供有希望的人使用。
祝你好运。
我找到问题了!!
我在代码的最开始使用了 askopenfilename()
,它打开了一个额外的 Tkinter
window。结果有两个Tkinter
windows打开了程序,把程序搞糊涂了。
通过将所有内容发送到创建的第一个 Tk
window(并删除第二个),它解决了问题。