- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试将一些 Python 2.7 代码重构为 Eclipse 中的新方法。当我在下面用注释标记的 block 上使用 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()
有人可以解释为什么图像消失并提出一个解决方案,以便我可以在不丢失图像的情况下进行重构吗?
重构后:
from Tkinter import Tk, Button, W, E, N, S, Label, Frame
from PIL import Image, ImageTk
def extractedMethod(root):
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)
def myCallback():
pass
root = Tk()
extractedMethod(root)
root.mainloop()
谢谢。
最佳答案
问题在于您过早释放 PhotoImage
对象。
如the docs解释一下:
You must keep a reference to the image object in your Python program, either by storing it in a global variable, or by attaching it to another object.
Note: When a PhotoImage object is garbage-collected by Python (e.g. when you return from a function which stored an image in a local variable), the image is cleared even if it’s being displayed by a Tkinter widget.
To avoid this, the program must keep an extra reference to the image object. A simple way to do this is to assign the image to a widget attribute, like this:
label = Label(image=photo)
label.image = photo # keep a reference!
label.pack()
您可能认为将其作为 image
参数传递给 Label
构造函数可以使其保持事件状态。但事实并非如此; Label
实际上并不保留对 PhotoImage
对象本身的引用,它只是在 mainloop
之后运行的 Tcl 代码中的实际标签构造开始这样做。 (它类似于弱引用,但不是有意或明确的引用,如果有帮助的话。)
因此,快速而肮脏的解决方案是将其添加到 extractedMethod
的顶部:
global photo1
...或在 label1 = Label(image=photo1)
行之后添加此内容:
label1.photo = photo1
<小时/>
避免这种情况的更好方法是使用面向对象设计而不是平面过程设计,这样您就有一些合理的对象来拥有所有引用。
即使是简单的版本,如these examples所示会起作用:
class Foo(object):
def __init__(self, root):
# put the code from extractedMethod here,
# but prefix every local variable with self,
# and do the same for myCallback.
def myCallback(self):
pass
但你可能最好采用真正的面向对象设计,其中你的对象实际上代表某些东西,如the official examples :
class MyFrame(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.pack()
self.create_widgets()
def myCallback(self):
pass
def create_widgets(self):
# put the code from extractedMethod here,
# again prefixing things with self
关于python - Python 中的重构(在 Eclipse 中提取新方法),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18665973/
如果有人能为我分解它,让我能理解它,我会非常感激。我知道它用于通过 apply 方法创建新对象。 Function.prototype.new = function () { var args
新版本的HADOOP中有一个方法。http://hadoop.apache.org/docs/current/api/org/apache/hadoop/fs/FileSystem.html#conc
根据支持库变更日志和 Fragment 类文档 ( https://developer.android.com/reference/android/support/v4/app/Fragment.ht
根据支持库更改日志和 Fragment 类文档 (https://developer.android.com/reference/android/support/v4/app/Fragment.htm
执行Async BigJob() 的无限运行任务的正确方法是什么?并且可以根据要求停止 提示:我正在尝试学习 [一种] 新方法来更新我现有的策略。 我有一个简单的程序(测试程序),它有一个开始 和停止
我将解释我的想法:我使用 python 作为谷歌应用程序引擎 + js + css 主项目将存储在 src 文件夹下,如下所示:\src \app <--- 这里是 gae 的所有 python 应用
我是一名优秀的程序员,十分优秀!