I'm attempting to add a .jpeg
image to my GUI while it has several other widgets.
With my code, I can display the image in a separate Tkinter
window when I use the following command:
#self.label = Label(image = self.img)
However, whenever I try to add the image to the original Tkinter
window, I get the error seen below my code. The way I tried to add it to the original Tkinter window is:
#self.label = Label(frame, image = self.img)
Oddly enough, when I try to replicate the error in a shorter version of the code (such as directly below), it works. HOWEVER! To replicate the error in the shortened code, you need to create a different error first. Example: Replace text = "Try"
with text = "%s" %yikes
(because there is no variable yikes
it will give you an error). After you change the code back to the EXACT way it was before, it produces the error I've descried below (TclError: image "pyimage__" doesn't exit
). At the very bottom, I've included the entire class since I'm having difficulty consistently replicating the issue. I'm using Python 2.7 and 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()
I found the issue!!
I used askopenfilename()
in the very beginning of my code, which opened an extra Tkinter
window. As a result, there were two Tkinter
windows open and confused the program.
By sending everything to the first Tk
window that was created (and removing the second), it resolved the issue.