Python:Tkinter TclError:无法调用“图像”命令

Posted

技术标签:

【中文标题】Python:Tkinter TclError:无法调用“图像”命令【英文标题】:Python: Tkinter TclError: can't invoke "image" command 【发布时间】:2019-01-29 20:27:41 【问题描述】:

前言:我目前已经尝试了大多数事情,在 *** 上关于这个问题的问题很少,我似乎无法理解它,所以我需要一些帮助

应用程序:这个程序的目的是为一个椭圆和一张图片制作动画,椭圆效果很好,但是图片很吃力,你可以删除图片或alien2 并且程序应该可以正常运行。

代码

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

错误:

image

runfile('/Users/Stian/.spyder-py3/animation_test.py', wdir='/Users/Stian/.spyder-py3') Traceback(最近一次调用最后一次):

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

文件“/anaconda3/lib/python3.6/site-packages/spyder/utils/site/sitecustomize.py”,第 705 行,在运行文件中 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 中 self.__photo = tkinter.PhotoImage(**kw)

文件“/anaconda3/lib/python3.6/tkinter/init.py”,第 3542 行,在 init Image.init(self, 'photo', name, cnf, master, **kw)

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

TclError: 无法调用“图像”命令:应用程序已被销毁


我知道代码并不漂亮,但它是一个测试环境,如上所述,一切都应该完美无瑕,但是当使用图像而不是椭圆形时它会中断,这应该不会有太大的区别。提前致谢!


问题已解决

原来在 PhotoImage() 中分配 master 时出现了问题,当我删除应用程序没有得到 TclError

新问题

我对代码所做的更改来自于此:

        self.cardPath = Image.open('bubble.png')
        self.resCard = cardPath.resize((100,100))
        self.CardVar = ImageTk.PhotoImage(resCard,master=root)

到这里:

    self.cardPath = Image.open('bubble.png')
    self.resCard = cardPath.resize((100,100))
    self.CardVar = ImageTk.PhotoImage(resCard)

新错误

image form


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

文件“/anaconda3/lib/python3.6/site-packages/spyder/utils/site/sitecustomize.py”,第 705 行,在运行文件中 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(100,100,CardVar,anchor=CENTER)

文件“/anaconda3/lib/python3.6/tkinter/init.py”,第 2486 行,在 create_image return self._create('image', args, kw)

文件“/anaconda3/lib/python3.6/tkinter/init.py”,第 2477 行,在 _create *(args + self._options(cnf, kw))))

TclError: 未知选项“pyimage21”

【问题讨论】:

我们不需要看到图像形式的代码或错误。但是,如果您提供“bubble.png”图像会很好。 【参考方案1】:

您的代码中有几个地方忘记了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 无法自行更新或响应任何用户输入。最好重新组织您的代码,以便 animation 使用 .after 方法。

这是一个不使用sleepanimation 方法版本。您需要将self.count = 0 添加到__init__ 方法中。

 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)

【讨论】:

感谢您的反馈,非常感谢!我也注意到了,问题是我从来没有在我的主应用程序中将它分配为一个 kwarg,但我决定尝试它,它仍然给我同样的错误。我也尝试了您的代码,但不幸的是仍然没有运气:(另外,感谢您的努力以及关于在 GUI 中使用 time.sleep() 的评论,我也会对此进行研究!编辑:会 1 提升你如果我有权力 @Stanley 这很奇怪,它在我的机器上运行正常(使用我自己的一张 PNG 图像而不是 bubble.png)。尝试直接在命令行上运行它,而不是在 Spyder 中。 好主意!我这样做了,它似乎无法找到bubble.png,尽管您可以在这张图片中看到它:oi68.tinypic.com/fk5pfl.jpg @Stanley "bubble.png" 是否位于启动脚本的同一目录中(可能不是包含脚本的目录)?如果没有,你应该把它放在那里。或者在您的Image.open 调用中提供“bubble.png”的完整路径。 @Stanley 太好了!我很高兴你能解开这个小谜团。 :)【参考方案2】:

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

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() 并且另一个位于很远的图像出现了,所以看起来像是保存了一些东西我的记忆。所以我决定重启内核,一切顺利

【讨论】:

以上是关于Python:Tkinter TclError:无法调用“图像”命令的主要内容,如果未能解决你的问题,请参考以下文章

Python系列_tkinter.TclError: no display name and no $DISPLAY environment variable

python3 tkinter报错:_tkinter.TclError: cannot use geometry manager pack inside . which already has sla

Python:Tkinter TclError:无法调用“图像”命令

tkinter TclError:找不到包 treectrl

为啥我会收到 tkinter.TclError: bitmap not defined 错误?

tkinter ttk 主题:_tkinter.TclError:不支持图像文件格式“svg”