简体   繁体   English

Tkinter在按下按钮时不会改变图像

[英]Tkinter not changing image on button press

I have loaded an image to tkinter label and that image is diplayed in that label.When i press the button i need to change that image.When the button is pressed older image is gone but the new image is not displayed My code is我已将图像加载到 tkinter 标签,该图像显示在该标签中。当我按下按钮时,我需要更改该图像。按下按钮时,旧图像消失了,但新图像未显示我的代码是

import Tkinter as tk
from PIL import Image, ImageTk
root = tk.Tk()

def change_pic(labelname):
 photo1 = ImageTk.PhotoImage(Image.open("demo.jpg"))
 labelname.configure(image=photo1)
 print "updated"

vlabel=tk.Label(root)
photo = ImageTk.PhotoImage(Image.open('cardframe.jpg'))
vlabel.configure(image=photo)
vlabel.pack()
b2=tk.Button(root,text="Capture",command=lambda:change_pic(vlabel))
b2.pack()
root.mainloop()

In def change_pic(labelname) , you need to add labelname.photo = photo1 to make sure photo1 not being garbage collected.def change_pic(labelname) ,您需要添加labelname.photo = photo1以确保photo1不会被垃圾收集。

def change_pic(labelname):
    photo1 = ImageTk.PhotoImage(Image.open("demo.jpg"))
    labelname.configure(image=photo1)
    labelname.photo = photo1
    print "updated"

PS Looks like both labelname.photo = photo1 and labelname.image = photo1 work. PS看起来labelname.photo = photo1labelname.image = photo1工作。

Check this out for more details: http://effbot.org/tkinterbook/label.htm查看更多详细信息: http : //effbot.org/tkinterbook/label.htm

You can use the label to display PhotoImage and BitmapImage objects.您可以使用标签来显示 PhotoImage 和 BitmapImage 对象。 When doing this, make sure you keep a reference to the image object, to prevent it from being garbage collected by Python's memory allocator.执行此操作时,请确保保留对图像对象的引用,以防止 Python 的内存分配器对其进行垃圾回收。 You can use a global variable or an instance attribute, or easier, just add an attribute to the widget instance.您可以使用全局变量或实例属性,或者更简单,只需向小部件实例添加一个属性即可。

The following edits were made:进行了以下编辑:

  1. I have organised your code layout and simplified its syntax where possible.我已经组织了您的代码布局并尽可能简化了其语法。 These are to make your code easier to read.这些是为了使您的代码更易于阅读。
  2. Commonly we make the PIL objects a subset/children of tk.通常我们将 PIL 对象作为 tk 的子集/子对象。 So long it is a part of root (ie it is a child of the root or any of its child widgets), your PIL objects will work.只要它是根的一部分(即它是根或其任何子部件的子部件),您的 PIL 对象就可以工作。

Your working code is shown below:您的工作代码如下所示:

import Tkinter as tk
from PIL import Image, ImageTk

def change_pic():
    vlabel.configure(image=root.photo1)
    print "updated"

root = tk.Tk()

photo = 'cardframe.jpg'
photo1 = "demo.jpg"
root.photo = ImageTk.PhotoImage(Image.open(photo))
root.photo1 = ImageTk.PhotoImage(Image.open(photo1))

vlabel=tk.Label(root,image=root.photo)
vlabel.pack()

b2=tk.Button(root,text="Capture",command=change_pic)
b2.pack()

root.mainloop()

I got it working with one more line of code:我用另一行代码让它工作:

import tkinter as tk                        # I am using python 3 on windows so the tkinter is lowercased
from PIL import Image, ImageTk
root = tk.Tk()

def change_pic(labelname):
    global photo1                           # This is the only new line you need, I believe
    photo1 = ImageTk.PhotoImage(Image.open("demo.jpg"))
    labelname.configure(image=photo1)
    print("updated")                        # Again I'm using python 3 on windows so syntax may differ.
    root.update()                           # You don't need this statement in this case, but it never hurts

vlabel=tk.Label(root)
photo = ImageTk.PhotoImage(Image.open('cardframe.jpg'))
vlabel.configure(image=photo)
vlabel.pack()
b2=tk.Button(root,text="Capture",command=lambda:change_pic(vlabel))
b2.pack()
root.mainloop()

I believe that the code changes the image locally, so the global statement will change it on the project scope.我相信代码在本地更改了图像,因此全局声明会在项目范围内更改它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM