2006-10-06

在Python Tk中显示图像的一个小问题

最近在用Python做一个小东西,需要将一幅图片(JPG的)显示出来。我选择使用了Python自带现成的Tkinter库,而没有使用wxPython。这要使用PhotoImage结合Label部件来做显示,但因为Tkinter的PhotoImage支持的文件格式较少,另外又用到了PIL来读入图像并提供给部件,死活图像就是显示不出来,代码如下:


1 from Tkinter import *
2 from PIL import ImageTk, Image
3
4 class App(Frame):
5 def __init__(self, master=None):
6 Frame.__init__(self, master=master)
7 file = "C:\\Develope\\printer.gif"
8 self.ima = Label(master, image=ImageTk.PhotoImage(Image.open(file)), bd=0)
9 self.ima.pack(fill="both", anchor="w", side="top", expand=1)
10
11 root = Tk()
12 app = App(master=root)
13 app.mainloop()
14
以上这段代码虽然能运行,但无法显示图像,我百思不得其解,翻阅了很多资料,并没有发现我的代码在哪儿有问题,我还一直以为是Tk的某个开关弄错了,后来找到了一个例子,仔细对比之后,发现了一个小问题——这个例子中是将ImageTk.PhotoImage的实例作为对象的成员变量存储的,而我是直接作为引用传递过去了,知道了这一点之后,我将代码改写成这样:

1 from Tkinter import *
2 from PIL import ImageTk, Image
3
4 class App(Frame):
5 def __init__(self, master=None):
6 Frame.__init__(self, master=master)
7 file = "C:\\Develope\\printer.gif"
8 self.im = ImageTk.PhotoImage(Image.open(file))
9 self.ima = Label(master, image=self.im, bd=0)
10 self.ima.pack(fill="both", anchor="w", side="top", expand=1)
11
12 root = Tk()
13 app = App(master=root)
14 app.mainloop()
15
图像就顺利显示出来了。
但依然一些不明白的地方,原先我的图像去哪儿了呢?莫非被垃圾收集器给回收了?难道Tk的模块不使用引用?看来还得请教高手啊。

5 条评论:

billconan 说...

曹兄现在做代码高亮显示的区域是什么现成的js吗,我也想弄一个。
前天也发现新版的google group了,发现整合了一些google pages的东西,但是上传速度比较慢。
wxPython就是wxwidgets的python port吧,感觉它里面图像库把alpha和rgb两个数据分开有点怪异,尤其要生成贴图的时候。

Unknown 说...

PHP的我用GeSHi
这篇文章里面我用Vim生成的代码,因为Geshi的有点问题
那个JavaScript的高亮工具是 http://www.dreamprojections.com/SyntaxHighlighter/

billconan 说...

原来用的不是一个万能的高亮工具啊,我先前找到过一个javascript的高亮,支持很多语言,但是好像blogger发布代码有问题,不能自动转换大于号小于号这些符号成转义字符,还要手动修改,很麻烦啊。我给blogger提了好多bug了,好像都不改。

光华门外 说...

多谢lz的文章啊,我也是遇到这个问题,百思不得其解啊

Haisheng HU 说...

没错,加个引用就是为了防止垃圾回收的。