我正在制作一个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:无法调用“image”命令:应用程序已被破坏
我无法弄清楚出了什么问题。我无法移动图像命令,不知怎的,我需要“保存”它,以免它被破坏。我知道这里还有其他代码错误,但我认为如果我弄清楚我得到的TclError,我可以直接设置其他一切。
如果有更简单的方法可以做到这一切,请告诉我们!
答案 0 :(得分:2)
我已经四处寻找一个很好的解决方案但尚未找到合适的解决方案。查看Tkinter.py类,看起来Image del 值为:
def __del__(self):
if self.name:
try:
self.tk.call('image', 'delete', self.name)
except TclError:
# May happen if the root was destroyed
pass
这意味着如果您想要执行 BRUTAL 黑客攻击,可以按照jtp链接中的说明设置PhotoImage。
photo = tk.PhotoImage(file="C:/myimage.gif")
widget["image"] = photo
widget.image = photo
然后你可以在退出程序之前做下面的黑客攻击:
photo.name = None
这样可以防止它在PhotoImage删除时尝试自我清理,并防止在 del 方法中调用异常。我不建议你这样做,除非你的背靠墙,你别无选择。
我将继续研究这个问题,如果我找到更好的解决方案,我会用更好的方法编辑这篇文章(希望有人会在此之前提供正确的解决方案)。
答案 1 :(得分: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类的好链接。
答案 2 :(得分:0)
似乎你没有理解Event-driven programming。您应该创建一次完整的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()