我正在尝试在Eclipse中将一些Python2.7代码重构成一个新方法。在下面用注释标记的块上使用Eclipse的Refactoring->Extract method
之后,我的图像不再显示在GUI中:
from Tkinter import Tk, Button, W, E, N, S, Label, Frame
from PIL import Image, ImageTk
def myCallback():
pass
root = Tk()
# start refactor method here
root.geometry('400x400')
runButton = Button(root, text="Run",bg='green',
command=myCallback)
runButton.grid(row=2, column=0,
padx=10, pady=10)
quitButton = Button(root, text="Quit",
command=root.quit)
quitButton.grid(row=2, column=1,
padx=10, pady=10)
frame1 = Frame(width=200, height=200)
frame1.grid(row=1, column=0, columnspan=1, rowspan=1,
sticky=W+E+N+S, padx=10, pady=10)
image1 = Image.open("C:/Users/me/Pictures/house.jpg")
size = 64,64
image1.thumbnail(size, Image.ANTIALIAS)
photo1 = ImageTk.PhotoImage(image1)
label1 = Label(image=photo1)
label1.grid(row=0, column=10, columnspan=1, rowspan=1,
sticky=N+E, padx=10, pady=10)
# end refactor method here
root.mainloop()
有人能解释一下为什么图像会消失,并提出一个解决方案,这样我就可以在不丢失图像的情况下进行重构?在
重构后:
^{pr2}$谢谢。在
问题是您过早地释放了
PhotoImage
对象。在如the docs解释:
您可能认为将其作为
image
参数传递给Label
构造函数可以使其保持活动状态。但是它没有;Label
实际上并没有保留对PhotoImage
对象的引用,只有在mainloop
开始之后运行的Tcl代码中的实际标签构造才这样做。(这类似于弱引用,但不是有意的或明确的引用,如果有帮助的话)因此,快速而棘手的解决方案是要么将其添加到
^{pr2}$extractedMethod
的顶部:…或在
label1 = Label(image=photo1)
行后添加:避免这种情况的一个更好的方法是使用OO设计而不是平面过程设计,这样您就有了一些合理的对象来拥有所有的引用。在
即使是琐碎的版本,如these examples所示也可以:
但是你最好使用一个真正的OO设计,你的对象实际上代表一些东西,比如the official examples:
一种解决方案是在
extractedMethod()
的开头添加一行:问题是,否则
photo1
是一个局部变量,一旦函数返回就会被丢弃,因此在函数中对它的引用将变得无效。在有人可能会认为
label1 = Label(image=photo1)
语句会增加它的引用计数并阻止这种情况的发生,但显然它不是这样工作的。我以前见过这种情况,我个人怀疑这是由于Tkinter
中的一个错误引起的。。。在相关问题 更多 >
编程相关推荐