问题
preface: I have currently tried most things and there are few qusestions asked on stackoverflow on this question and i cant seem to wrap my head around it so im going to need some help
application: the purpose of this program is to animate an oval and a picture, the oval works fine, but the picture is struggling, you could remove the image or alien2 and the program should run fine.
CODE
image form
from tkinter import *
import time
from PIL import Image,ImageFilter
from PIL import ImageTk
class alien(object):
def __init__(self):
self.root = Tk()
self.canvas = Canvas(self.root, width=400, height = 400)
self.canvas.pack()
self.cardPath = Image.open('bubble.png')
self.resCard = cardPath.resize((100,100))
self.CardVar = ImageTk.PhotoImage(resCard,master=root)
self.alien1 = self.canvas.create_oval(20, 260, 120, 360, outline='white',fill='blue')
self.alien2 = self.canvas.create_image(100,100,CardVar,anchor=CENTER)
self.canvas.pack()
self.root.after(0, self.animation)
self.root.mainloop()
def animation(self):
track = 0
while True:
x = 5
y = 0
if track == 0:
for i in range(0,51):
time.sleep(0.025)
self.canvas.move(self.alien1, x, y)
self.canvas.move(self.alien2, x, y)
self.canvas.update()
track = 1
print("check")
else:
for i in range(0,51):
time.sleep(0.025)
self.canvas.move(self.alien1, -x, y)
self.canvas.move(self.alien2, -x, y)
self.canvas.update()
track = 0
print(track)
alien()
ERROR:
image
runfile('/Users/Stian/.spyder-py3/animation_test.py', wdir='/Users/Stian/.spyder-py3') Traceback (most recent call last):
File "", line 1, in runfile('/Users/Stian/.spyder-py3/animation_test.py', wdir='/Users/Stian/.spyder-py3')
File "/anaconda3/lib/python3.6/site-packages/spyder/utils/site/sitecustomize.py", line 705, in runfile execfile(filename, namespace)
File "/anaconda3/lib/python3.6/site-packages/spyder/utils/site/sitecustomize.py", line 102, in execfile exec(compile(f.read(), filename, 'exec'), namespace)
File "/Users/Stian/.spyder-py3/animation_test.py", line 57, in alien()
File "/Users/Stian/.spyder-py3/animation_test.py", line 25, in init self.CardVar = ImageTk.PhotoImage(resCard,master=root)
File "/anaconda3/lib/python3.6/site-packages/PIL/ImageTk.py", line 124, in init self.__photo = tkinter.PhotoImage(**kw)
File "/anaconda3/lib/python3.6/tkinter/init.py", line 3542, in init Image.init(self, 'photo', name, cnf, master, **kw)
File "/anaconda3/lib/python3.6/tkinter/init.py", line 3498, in init self.tk.call(('image', 'create', imgtype, name,) + options)
TclError: can't invoke "image" command: application has been destroyed
I know the code is not beautiful, but it's a test environment and as mentioned everything should work flawless, but it breaks when an image is used instead of an oval which should not make a big difference. Thanks in advance!
PROBLEM SOLVED
turns out the problem turned up when assigning master inside PhotoImage(), when i removed that the application did not get the TclError
NEW PROBLEM
the changes i made to the code were from this:
self.cardPath = Image.open('bubble.png')
self.resCard = cardPath.resize((100,100))
self.CardVar = ImageTk.PhotoImage(resCard,master=root)
to this:
self.cardPath = Image.open('bubble.png')
self.resCard = cardPath.resize((100,100))
self.CardVar = ImageTk.PhotoImage(resCard)
THE NEW ERROR
image form
File "", line 1, in runfile('/Users/Stian/.spyder-py3/animation_test.py', wdir='/Users/Stian/.spyder-py3')
File "/anaconda3/lib/python3.6/site-packages/spyder/utils/site/sitecustomize.py", line 705, in runfile execfile(filename, namespace)
File "/anaconda3/lib/python3.6/site-packages/spyder/utils/site/sitecustomize.py", line 102, in execfile exec(compile(f.read(), filename, 'exec'), namespace)
File "/Users/Stian/.spyder-py3/animation_test.py", line 56, in alien()
File "/Users/Stian/.spyder-py3/animation_test.py", line 27, in init self.alien2 = self.canvas.create_image(100,100,CardVar,anchor=CENTER)
File "/anaconda3/lib/python3.6/tkinter/init.py", line 2486, in create_image return self._create('image', args, kw)
File "/anaconda3/lib/python3.6/tkinter/init.py", line 2477, in _create *(args + self._options(cnf, kw))))
TclError: unknown option "pyimage21"
回答1:
You have a few places in your code where you forgot self
. But the cause of your main error is that you need to pass the image name as a keyword arg. Here's a repaired version of your code.
from tkinter import *
import time
from PIL import Image,ImageFilter
from PIL import ImageTk
class alien(object):
def __init__(self):
self.root = Tk()
self.canvas = Canvas(self.root, width=400, height=400)
self.canvas.pack()
self.cardPath = Image.open('bubble.png')
self.resCard = self.cardPath.resize((100, 100))
self.CardVar = ImageTk.PhotoImage(self.resCard)
self.alien1 = self.canvas.create_oval(20, 260, 120, 360, outline='white', fill='blue')
self.alien2 = self.canvas.create_image(100, 100, image=self.CardVar, anchor=CENTER)
self.canvas.pack()
self.root.after(0, self.animation)
self.root.mainloop()
def animation(self):
track = 0
while True:
x = 5
y = 0
if track == 0:
for i in range(51):
time.sleep(0.025)
self.canvas.move(self.alien1, x, y)
self.canvas.move(self.alien2, x, y)
self.canvas.update()
track = 1
print("check")
else:
for i in range(51):
time.sleep(0.025)
self.canvas.move(self.alien1, -x, y)
self.canvas.move(self.alien2, -x, y)
self.canvas.update()
track = 0
print(track)
alien()
BTW, it's not a good idea to use time.sleep
in GUI programs. It puts everything to sleep, so the GUI cannot update itself, or respond to any user input. It would be better to reorganize your code so that animation
uses the .after
method.
Here's a version of the animation
method that doesn't use sleep
. You need to add self.count = 0
to the __init__
method.
def animation(self):
y = 0
x = 5 if self.count < 50 else -5
self.count = (self.count + 1) % 100
self.canvas.move(self.alien1, x, y)
self.canvas.move(self.alien2, x, y)
self.root.after(25, self.animation)
回答2:
After a while i edited the code and made it work. here is the full code
from tkinter import *
import time
import PIL
from PIL import Image,ImageFilter
from PIL import ImageTk
class alien(object):
def __init__(self):
self.root = Tk()
self.canvas = Canvas(self.root, width=400, height = 400)
self.canvas.pack()
CardVar = ImageTk.PhotoImage(file='bubble.png')
self.alien1 = self.canvas.create_oval(20, 260, 120, 360, outline='white',fill='blue')
self.alien2 = self.canvas.create_image((100,100),image=CardVar,anchor=CENTER)
self.canvas.pack()
self.root.after(0, self.animation)
self.root.mainloop()
def animation(self):
track = 0
while True:
x = 5
y = 0
if track == 0:
for i in range(0,51):
time.sleep(0.025)
self.canvas.move(self.alien1, x, y)
self.canvas.move(self.alien2, x, y)
self.canvas.update()
track = 1
print("check")
else:
for i in range(0,51):
time.sleep(0.025)
self.canvas.move(self.alien1, -x, y)
self.canvas.move(self.alien2, -x, y)
self.canvas.update()
track = 0
print(track)
alien()
The problem
the cardVar was never able to find the correct image even though it was in the same folder, so i tried to do cardVar.show() and another image that was located far away showed up so it seems like something was saved in my memory. so i decided to restart kernel and everything went smooth
来源:https://stackoverflow.com/questions/51986128/python-tkinter-tclerror-cant-invoke-image-command