tkinter.TclError: image "pyimage3" doesn't exist
Question:
I’m having trouble with a function that shows an image for two seconds on screen, and then is destroyed. When the program runs the functions initial call procedurely works fine, but if the function is then called via a button built in tkinter I get an error.
appcwd = os.getcwd()
user32 = ctypes.windll.user32
screensize = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)
size = str(screensize[0])+'x'+str(screensize[1])
def wlcm_scrn(event=None):
def destroy_wlcm(event=None):
wlcm_scrn.destroy()
global appcwd
global screensize
wlcm_scrn = tkinter.Tk()
file=appcwd+"\Run_Files\splash.gif"
splsh_img = tkinter.PhotoImage(file=file)
splosh = tkinter.Label(wlcm_scrn,image=splsh_img)
wlcmh = splsh_img.height()/2
wlcmw = splsh_img.width()/2
splosh.pack()
wlcm_scrn.config(bg='black')
wlcm_scrn.overrideredirect(True)
wlcm_scrn.bind("<Escape>",destroy_wlcm)
wlxym = '+'+str(int((screensize[0]/2)-wlcmw))+'+'+str(int((screensize[1]/2)-wlcmh))
wlcm_scrn.geometry(wlxym)
wlcm_scrn.wm_attributes("-topmost", 1)
wlcm_scrn.after(2000,destroy_wlcm)
wlcm_scrn.mainloop()
wlcm_scrn() #Call through procedure.
Button that calls the function.
view_img = tkinter.Button(cfrm,text='Show splash image',command=wlcm_scrn)
Error message when called through button command.
Exception in Tkinter callback
Traceback (most recent call last):
File "C:Python33libtkinter__init__.py", line 1475, in __call__
return self.func(*args)
File "C:Python33POS_SolutionRattle_Hum_POS.py", line 1755, in run_wlcm_scrn
wlcm_scrn()
File "C:Python33POS_SolutionRattle_Hum_POS.py", line 34, in wlcm_scrn
splosh = tkinter.Label(wlcm_scrn,image=splsh_img)
File "C:Python33libtkinter__init__.py", line 2596, in __init__
Widget.__init__(self, master, 'label', cnf, kw)
File "C:Python33libtkinter__init__.py", line 2075, in __init__
(widgetName, self._w) + extra + self._options(cnf))
_tkinter.TclError: image "pyimage3" doesn't exist
What is “pyimage3” and why doesn’t it exist?
Any help would be apprecaited. Thanks.
Answers:
I found the issue so figured I’d answer myself for anyone who has this issue in the future.
When the wlcm_scrn runs procedurely it is the only window that exists at that point in time, and so it can use tkinter.Tk(). The error arises because the button that calls the function is itself sitting in an active window that is also running as Tkinter.Tk(). So when Python/Tkinter tries to build wlcm_scrn from the button, it’s essentially trying to create two windows under root and falling over.
The solution:
Changing line…
wlcm_scrn = tkinter.Tk()
to this…
wlcm_scrn = tkinter.Toplevel()
…stops the error, and the image shows.
I personally am going to have two instances of the function. One called procedurely under Tk(), and one called within the application under TopLevel().
Maybe not for this exact case, but for a similar one, I found that the customary
if __name__ == '__main__':
wlcm_scrn() #Call through procedure.
solves the problem as well.
This seems to kill the active window and to create a new one each time you re-call the same module.
The PhotoImage method creates an image for the first TK () instance created.
Thus, it seems to have solved to inherit TK () instance by replacing TopLevel ().
This can be solved by specifying the master of the Tk () instance as the option of PhotoImage.
I think this should be changed.:
splsh_img = tkinter.PhotoImage(file=file,master=wlcm_scrn)
I had been getting the same error, and the above methods work well to fix it, but i also found that if you aren’t going to be changing all of this, then you can restart the kernel (in jupyter notebook) or restart your python interpreter
And that should make it work the next time. I am not entirely sure how and why this works tho, but it does and is a simple solution for the time being
from tkinter import *
import tkinter as tk
window = tk.Tk()
window.title('Learn')
window.geometry("500x500")
text = Label(window, text = 'label here')
text.pack()
photo = PhotoImage(file='C:\Users\user\Documents\image\image_2.png')
labelphoto = Label(window , image = photo)
labelphoto.pack()
window.mainloop()enter code here
I’m having trouble with a function that shows an image for two seconds on screen, and then is destroyed. When the program runs the functions initial call procedurely works fine, but if the function is then called via a button built in tkinter I get an error.
appcwd = os.getcwd()
user32 = ctypes.windll.user32
screensize = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)
size = str(screensize[0])+'x'+str(screensize[1])
def wlcm_scrn(event=None):
def destroy_wlcm(event=None):
wlcm_scrn.destroy()
global appcwd
global screensize
wlcm_scrn = tkinter.Tk()
file=appcwd+"\Run_Files\splash.gif"
splsh_img = tkinter.PhotoImage(file=file)
splosh = tkinter.Label(wlcm_scrn,image=splsh_img)
wlcmh = splsh_img.height()/2
wlcmw = splsh_img.width()/2
splosh.pack()
wlcm_scrn.config(bg='black')
wlcm_scrn.overrideredirect(True)
wlcm_scrn.bind("<Escape>",destroy_wlcm)
wlxym = '+'+str(int((screensize[0]/2)-wlcmw))+'+'+str(int((screensize[1]/2)-wlcmh))
wlcm_scrn.geometry(wlxym)
wlcm_scrn.wm_attributes("-topmost", 1)
wlcm_scrn.after(2000,destroy_wlcm)
wlcm_scrn.mainloop()
wlcm_scrn() #Call through procedure.
Button that calls the function.
view_img = tkinter.Button(cfrm,text='Show splash image',command=wlcm_scrn)
Error message when called through button command.
Exception in Tkinter callback
Traceback (most recent call last):
File "C:Python33libtkinter__init__.py", line 1475, in __call__
return self.func(*args)
File "C:Python33POS_SolutionRattle_Hum_POS.py", line 1755, in run_wlcm_scrn
wlcm_scrn()
File "C:Python33POS_SolutionRattle_Hum_POS.py", line 34, in wlcm_scrn
splosh = tkinter.Label(wlcm_scrn,image=splsh_img)
File "C:Python33libtkinter__init__.py", line 2596, in __init__
Widget.__init__(self, master, 'label', cnf, kw)
File "C:Python33libtkinter__init__.py", line 2075, in __init__
(widgetName, self._w) + extra + self._options(cnf))
_tkinter.TclError: image "pyimage3" doesn't exist
What is “pyimage3” and why doesn’t it exist?
Any help would be apprecaited. Thanks.
I found the issue so figured I’d answer myself for anyone who has this issue in the future.
When the wlcm_scrn runs procedurely it is the only window that exists at that point in time, and so it can use tkinter.Tk(). The error arises because the button that calls the function is itself sitting in an active window that is also running as Tkinter.Tk(). So when Python/Tkinter tries to build wlcm_scrn from the button, it’s essentially trying to create two windows under root and falling over.
The solution:
Changing line…
wlcm_scrn = tkinter.Tk()
to this…
wlcm_scrn = tkinter.Toplevel()
…stops the error, and the image shows.
I personally am going to have two instances of the function. One called procedurely under Tk(), and one called within the application under TopLevel().
Maybe not for this exact case, but for a similar one, I found that the customary
if __name__ == '__main__':
wlcm_scrn() #Call through procedure.
solves the problem as well.
This seems to kill the active window and to create a new one each time you re-call the same module.
The PhotoImage method creates an image for the first TK () instance created.
Thus, it seems to have solved to inherit TK () instance by replacing TopLevel ().
This can be solved by specifying the master of the Tk () instance as the option of PhotoImage.
I think this should be changed.:
splsh_img = tkinter.PhotoImage(file=file,master=wlcm_scrn)
I had been getting the same error, and the above methods work well to fix it, but i also found that if you aren’t going to be changing all of this, then you can restart the kernel (in jupyter notebook) or restart your python interpreter
And that should make it work the next time. I am not entirely sure how and why this works tho, but it does and is a simple solution for the time being
from tkinter import *
import tkinter as tk
window = tk.Tk()
window.title('Learn')
window.geometry("500x500")
text = Label(window, text = 'label here')
text.pack()
photo = PhotoImage(file='C:\Users\user\Documents\image\image_2.png')
labelphoto = Label(window , image = photo)
labelphoto.pack()
window.mainloop()enter code here