Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python代码问题,应用程序被破坏Tcl错误_Python_Windows_Tkinter_Pythonw - Fatal编程技术网

Python代码问题,应用程序被破坏Tcl错误

Python代码问题,应用程序被破坏Tcl错误,python,windows,tkinter,pythonw,Python,Windows,Tkinter,Pythonw,我正在制作一个Tkinter GUI,除了调用图像之外什么都不做——当然,我一直在努力寻找像样的Tkinter文档 我的代码中有一行似乎无法按要求执行-我想调用字典中的所有值,并在调用下一个值之前分别打印和提取每个值的同名图像。我试过dict.itervalues()和dict.values(),但似乎什么都想不出来 无论如何,下面是一个片段: for key in ansDict.iterkeys(): #using the iterkeys function... kind of x

我正在制作一个Tkinter GUI,除了调用图像之外什么都不做——当然,我一直在努力寻找像样的Tkinter文档

我的代码中有一行似乎无法按要求执行-我想调用字典中的所有值,并在调用下一个值之前分别打印和提取每个值的同名图像。我试过dict.itervalues()和dict.values(),但似乎什么都想不出来

无论如何,下面是一个片段:

for key in ansDict.iterkeys(): #using the iterkeys function... kind of
    x=key

    root = tk.Tk() # root window created (is this in the right place?)
    root.title('C H E M I S T R Y   A B C\'s')

    frameAns=tk.Frame(root)
    frameAns.grid(row=0, column=0, sticky=tk.NW)

    for i in range(len(ansDict[x])):
        print '-->' + ansDict[x][i]

    for value in ansDict.itervalues(): #This is the most important part

        for i in range(len(value)): #pulls value list from dictionary named ansDict
            picRef1 = Image.open(value[i] + '.jpg') #calls image file by the same name using PIL
            photo1 = ImageTk.PhotoImage(picRef1, master=root)

            button1 = tk.Button(frameAns, compound=tk.TOP, image=photo1, text=str(value[i]) + '\nClose me!', bg='white') #pulls up button onto which the image is pasted
            button1.grid(sticky=tk.NW, padx=2, pady=2) #places button on grid
            button1.image=photo1

            root.mainloop()
最后,在最后,它提取了一个或两个图像,然后我得到以下错误:

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

我也不知道怎么了。我无法移动image命令,我需要以某种方式“保存”它,这样它就不会被破坏。我知道这里还有其他的代码错误,但我认为如果我找出了我得到的错误,我可以把其他的一切都纠正过来


如果有更简单的方法,请告诉我

这里有一种可能性,尽管它的结构与您的示例不同。它将四幅100像素的正方形图像堆叠在一起。我认为您需要对每个图像对象保留一个单独的引用,因此我将它们隐藏在图像字典中

from Tkinter import *
import os
from PIL import Image, ImageTk

image_names = { '1':'one','2':'two','3':'three','4':'four' }
images = {}

root = Tk()
root.title("HELLO")
frm = Frame(root)

for v in image_names.itervalues():
   images[v] = {}
   images[v]['i']  = Image.open("%s%s.jpg" % (os.path.dirname(__file__), v))
   images[v]['pi'] = ImageTk.PhotoImage(images[v]['i'])
   images[v]['b']  = Button(frm, image=images[v]['pi'])
   images[v]['b'].pack()

frm.pack()

mainloop()
这里有一个讨论PhotoImage类的好链接


看来你没有想到。您应该一次性创建整个GUI,用小部件填充它,设置事件,然后进入无限循环。GUI应该根据事件到函数的绑定调用回调函数。因此,程序的这些部分应该只调用一次:
root=tk.tk()
root.mainloop()

编辑:添加了事件驱动编程“idea示例”


我已经四处寻找了一个很好的解决方案,但还没有找到合适的解决方案。查看Tkinter.py类,它看起来像Imagedel值:

def __del__(self):
    if self.name:
        try:
            self.tk.call('image', 'delete', self.name)
        except TclError:
            # May happen if the root was destroyed
            pass
这意味着如果你想做一个野蛮的黑客,你可以按照jtp链接中的描述设置一个照片图像

photo = tk.PhotoImage(file="C:/myimage.gif")
widget["image"] = photo
widget.image = photo
然后,您可以在程序退出之前执行以下操作:

photo.name = None
这将阻止它在PhotoImage delete中尝试清理自身,并防止在del方法中调用异常。我真的不建议你这样做,除非你背对着墙,你别无选择


我会继续研究这个问题,如果我找到更好的解决方案,我会用更好的解决方案编辑这篇文章(希望有人在那之前给出正确的解决方案)。

我不完全理解。我需要将我的根窗口构造函数和mainloop移到代码块之外,移到最外层(如果我对程序部分的引用错误,我很抱歉),并且只调用它们一次。我明白了。我还需要使用回调函数创建对根窗口内容的更改,这是我真的不知道如何做的部分。您非常了解第一部分。参见jtp的答案了解如何做,它提供了一个很好的例子。至于回调函数:几乎任何GUI的主要思想都是,当您设置小部件(例如Button)时,您可以将按下按钮时生成的事件绑定到某个函数。这种类型的函数称为
回调
。结果很简单,当你按下按钮时,函数被调用。我不使用Tk,所以我不是很确定,但我找到了一个很好的例子,所以我将把它添加到我的答案中。根据经验,当你的应用程序出现时,你应该被困在
mainloop
。你的应用程序在此之后所做的任何事情都应该通过回调函数来完成。将del方法改为:我能够在del方法中捕获异常,但很惊讶看到抛出了什么。(,TclError('can't invoke“image”command:application has destroming',))看起来是抛出了一个TclError(但没有被del捕获)。这让我想知道Tkinter的作者为了不看到这个问题做了什么…将进一步调查。
photo.name = None