Python:Tkinter错误:can';t调用;“图像”;命令

Python:Tkinter错误:can';t调用;“图像”;命令,python,python-3.x,tkinter,compiler-errors,spyder,Python,Python 3.x,Tkinter,Compiler Errors,Spyder,前言:我目前已经尝试了大多数方法,在这个问题上很少有人问我stackoverflow的问题,我似乎无法集中注意力,所以我需要一些帮助 应用程序:此程序的目的是为椭圆形和图片制作动画,椭圆形效果良好,但图片效果不佳,您可以删除图像或alien2,程序应该运行良好 代码 错误: 运行文件('/Users/Stian/.spyder-py3/animation_test.py',wdir='/Users/Stian/.spyder-py3') 回溯(最近一次呼叫最后一次): 文件“”,第1行,在

前言:我目前已经尝试了大多数方法,在这个问题上很少有人问我stackoverflow的问题,我似乎无法集中注意力,所以我需要一些帮助

应用程序:此程序的目的是为椭圆形和图片制作动画,椭圆形效果良好,但图片效果不佳,您可以删除图像或alien2,程序应该运行良好

代码


错误:

运行文件('/Users/Stian/.spyder-py3/animation_test.py',wdir='/Users/Stian/.spyder-py3') 回溯(最近一次呼叫最后一次):

文件“”,第1行,在 运行文件('/Users/Stian/.spyder-py3/animation_test.py',wdir='/Users/Stian/.spyder-py3')

文件“/anaconda3/lib/python3.6/site packages/spyder/utils/site/sitecustomize.py”,第705行,在runfile中 execfile(文件名、命名空间)

文件“/anaconda3/lib/python3.6/site packages/spyder/utils/site/sitecustomize.py”,第102行,在execfile中 exec(编译(f.read(),文件名,'exec'),命名空间)

文件“/Users/Stian/.spyder-py3/animation_test.py”,第57行,在 外国人()

文件“/Users/Stian/.spyder-py3/animation_test.py”,第25行,在init self.CardVar=ImageTk.PhotoImage(resCard,master=root)

文件“/anaconda3/lib/python3.6/site packages/PIL/ImageTk.py”,第124行,在init 自拍照=tkinter.PhotoImage(**kw)

文件“/anaconda3/lib/python3.6/tkinter/init.py”,第3542行,在init 图像。init(自我,“照片”,姓名,cnf,主机,**kw)

文件“/anaconda3/lib/python3.6/tkinter/init.py”,第3498行,在init self.tk.call(('image','create',imgtype,name,)+选项)

Tcl错误:无法调用“映像”命令:应用程序已被销毁


我知道代码并不漂亮,但它是一个测试环境,正如前面提到的,一切都应该完美无瑕地工作,但是当使用图像而不是椭圆形时,它就会崩溃,这不会造成很大的区别。提前谢谢


问题解决 事实证明,在分配master inside PhotoImage()时,当我删除应用程序未获得TCL错误时,出现了问题

新问题 我对代码所做的更改如下:

为此:


新错误


文件“”,第1行,在 运行文件('/Users/Stian/.spyder-py3/animation_test.py',wdir='/Users/Stian/.spyder-py3')

文件“/anaconda3/lib/python3.6/site packages/spyder/utils/site/sitecustomize.py”,第705行,在runfile中 execfile(文件名、命名空间)

文件“/anaconda3/lib/python3.6/site packages/spyder/utils/site/sitecustomize.py”,第102行,在execfile中 exec(编译(f.read(),文件名,'exec'),命名空间)

文件“/Users/Stian/.spyder-py3/animation_test.py”,第56行,在 外国人()

文件“/Users/Stian/.spyder-py3/animation_test.py”,第27行,在init self.alien2=self.canvas.create_image(100100,CardVar,anchor=CENTER)

文件“/anaconda3/lib/python3.6/tkinter/init.py”,第2486行,在创建图像中 返回自我。\u创建('image',args,kw)

文件“/anaconda3/lib/python3.6/tkinter/init.py”,第2477行,在创建 *(参数+自选项(cnf,kw)))

Tcl错误:未知选项“pyimage21”


您在代码中有几个地方忘记了
self
。但是,主要错误的原因是需要将图像名称作为关键字arg传递。这是您的代码的修复版本

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()
顺便说一句,在GUI程序中使用
time.sleep
不是一个好主意。它使所有内容处于休眠状态,因此GUI无法自我更新,也无法响应任何用户输入。最好重新组织代码,以便
动画
使用
.after
方法

 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)
这里有一个版本的
动画
方法,它不使用
睡眠
。您需要将
self.count=0
添加到
\uuuu init\uuu
方法中

 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)
def动画(自):
y=0
如果self.count小于50,则x=5,否则为-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)

过了一会儿,我编辑了代码并使其正常工作。这是完整的代码

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()
问题

cardVar始终无法找到正确的图像,即使它在同一个文件夹中,因此我尝试执行cardVar.show(),另一个位于远处的图像出现了,似乎有什么东西保存在我的内存中。所以我决定重启内核,一切都很顺利


我们不需要以图像形式查看代码或错误。但是如果你能提供“bubble.png”图片那就太好了。谢谢你的反馈,非常感谢!我也注意到了这一点,问题是我从来没有在我的主应用程序中将它指定为kwarg,但我决定尝试一下,它仍然会给我同样的错误。我也尝试了你的代码,但不幸的是仍然没有成功:(另外,感谢你的努力和关于在GUI中使用time.sleep()的评论,我也会研究一下!编辑:如果我有power@Stanley这很奇怪,它在我的机器上运行正常(使用我自己的一个PNG图像而不是bubble.PNG)。尝试直接在命令行上运行它,而不是在Spyder中运行。好主意!我这样做了,它似乎找不到bubble.png,尽管您可以在这张图片中看到:@Stanley是“bubble.png”,位于启动脚本的同一目录中(可能不是包含脚本的目录)如果没有,你应该把它放在那里。或者在你的
图像中给出“bubble.png”的完整路径。打开
呼叫。@Stanley好极了!我很高兴你是一个
 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)
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()