python - 在Toplevel小部件中显示图像时遇到奇怪问题

0 投票
3 回答
2261 浏览
提问于 2025-04-16 23:50

我正在用Python(2.5)制作一个“网页相册查看器”。

我用Tkinter来写图形界面,用urllib2从网上获取图片,用PIL来处理图片。

用户点击一个按钮后,会创建一个新的窗口,下载图片,然后在这个新窗口里显示出来。

这个按钮是绑定到一个叫“look”的方法上的。

所以代码大概是这样的:

class App:

  #some codes are omitted here

  def look(self, pic_url):
    top = Toplevel()
    more = More(top, pic_url)

class More:
  def __init__(self, master, pic_url):
    self.frame = Frame(master)
    self.frame.pack()
    response = urllib2.urlopen(pic_url)
    open("inner_temp.jpg", "wb+").write(response.read())
    self.picture = ImageTk.PhotoImage(file = "inner_temp.jpg")    
    self.photo_label = Label(self.frame, image = self.picture)
    self.photo_label.pack()

新窗口确实显示出来了,但里面什么都没有。我发现“inner_temp.jpg”这个文件确实在文件夹里下载下来了,但就是不显示。

更奇怪的是,如果我在代码的最后加上一个随便的字符,控制台窗口会显示错误信息,但图片却在新窗口里显示出来了!

  def look(self, pic_url):
    top = Toplevel()
    more = More(top, pic_url)

class More:
  def __init__(self, master, pic_url):
    self.frame = Frame(master)
    self.frame.pack()
    response = urllib2.urlopen(pic_url)
    open("inner_temp.jpg", "wb+").write(response.read())
    self.picture = ImageTk.PhotoImage(file = "inner_temp.jpg")    
    self.photo_label = Label(self.frame, image = self.picture)
    self.photo_label.pack()
    x

NameError: global name 'x' is not defined

这怎么可能发生呢!?我真的搞不明白!

有人能帮帮我吗?

谢谢,抱歉我的英语不好。

3 个回答

0

我没有看到更多的代码,但我猜测你可能忘记启动事件循环了。事件循环是让小部件(比如按钮、窗口等)自己更新的必要步骤。当你添加了那段会出错的代码时,这个错误会触发事件循环,从而让窗口刷新。

0

我猜可能是垃圾回收的问题。你可以试试下面这个:

class More:
  def __init__(self, master, pic_url):
    self.frame = Frame(master)
    self.frame.pack()
    response = urllib2.urlopen(pic_url)
    open("inner_temp.jpg", "wb+").write(response.read())
    self.frame.picture = ImageTk.PhotoImage(file = "inner_temp.jpg")    
    self.photo_label = Label(self.frame, image = self.frame.picture)
    self.photo_label.pack()
0

非常感谢大家!你们的回答和评论帮我解决了问题。 我终于找到了问题所在! 问题出在这里:

    class App:

  #some codes are omitted here

  def look(self, pic_url):
    top = Toplevel()
    more = More(top, pic_url)

应该是

    class App:

  #some codes are omitted here

  def look(self, pic_url):
    top = Toplevel()
    self.more = More(top, pic_url)

虽然我对Python的垃圾回收机制不太熟悉,但我认为图片只在出错时才显示的原因是,错误阻止了垃圾回收清理局部变量“more”的某些部分。而把局部变量换成实例变量“self.more”就解决了这个问题!

撰写回答