0

我正在制作一个 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()

最后,最后,它拉出一两个图像,然后我收到以下错误:

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

我不知道出了什么问题。我无法移动图像命令,并且我需要以某种方式“保存”它,以免它被破坏。我知道这里还有其他代码错误,但我认为如果我弄清楚我得到的 TclError,我可以将其他所有内容都设置好。

如果有更简单的方法来做这一切,请告诉!

4

3 回答 3

2

I have looked around for a good solution to this but have yet to find the proper solution. Looking at the Tkinter.py class it looks like the Image del value is:

def __del__(self):
    if self.name:
        try:
            self.tk.call('image', 'delete', self.name)
        except TclError:
            # May happen if the root was destroyed
            pass

This means if you wanted to do a BRUTAL hack you could setup a PhotoImage as described in jtp's link.

photo = tk.PhotoImage(file="C:/myimage.gif")
widget["image"] = photo
widget.image = photo

Then you could just before the program exited do the following hack:

photo.name = None

This would prevent it from trying to clean itself up in the PhotoImage delete and prevent the exception from being called in the del method. I do not really recommend you do this unless your back is up against the wall, and you have no alternative.

I will continue to look into this and if I find a better solution will edit this post with a better one (hopefully someone will give the correct solution before then).

于 2011-09-21T01:02:27.250 回答
0

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

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 类的好链接。

http://effbot.org/tkinterbook/photoimage.htm

于 2011-05-26T05:04:41.167 回答
0

看来您没有理解事件驱动编程的概念。您应该创建一次整个 GUI,用小部件填充它,设置事件,然后进入无限循环。GUI 应该根据您的事件到函数绑定调用回调函数。所以你程序的那些部分绝对应该只调用一次:root = tk.Tk(), root.mainloop().

编辑:添加了事件驱动的编程“想法示例”。

from Tkinter import *

master = Tk()

def callback():
    print "click!"

b = Button(master, text="OK", command=callback)
b.pack()

mainloop()
于 2011-05-26T05:06:12.023 回答