我正在尝试构建一个tkinter
按钮,该按钮将图像作为对象内部的背景。为什么第二种实现不起作用没有任何意义!
这里有3个非常简单的例子;谁能解释第二个实施不起作用的原因?
(Python 3.6.4 :: Anaconda,Inc。)
像魅力一样工作...
from tkinter import *
from PIL import Image, ImageTk
from numpy import random
w = Tk()
def cb():
print("Hello World")
image = ImageTk.PhotoImage(image=Image.fromarray(random.random((50,50))))
b = Button(w, text="text", command=cb, image=image)
b.pack()
w.mainloop()
A
内部创建的按钮该按钮在单击时不起作用,并且不显示图像:(。显然有问题,但我不理解...
from tkinter import *
from PIL import Image, ImageTk
from numpy import random
w = Tk()
class A():
def __init__(self, w):
image = ImageTk.PhotoImage(image=Image.fromarray(random.random((50,50))))
b = Button(w, text="text", command=self.cb, image=image)
b.pack()
def cb(self):
print("Hello World")
a = A(w)
w.mainloop()
A
内创建的没有背景图像的按钮按钮正常工作,但我也想显示图像
from tkinter import *
from PIL import Image, ImageTk
from numpy import random
w = Tk()
class A():
def __init__(self, w):
image = ImageTk.PhotoImage(image=Image.fromarray(random.random((50,50))))
b = Button(w, text="text", command=self.cb)#, image=image)
b.pack()
def cb(self):
print("Hello World")
a = A(w)
w.mainloop()
答案 0 :(得分:2)
您在这里有2个问题。
第一个问题是__init__
之后没有保存图像。您可能知道您需要保存对图像的引用才能在tkinter中使用它。您可能不知道在类中,如果不将图像分配给class属性,它将不会在__init__
之后保存图像。
因此,要解决第一个问题,您需要对此进行更改:
image = ImageTk.PhotoImage(image=Image.fromarray(random.random((50,50))))
对此:
# add self. to make it a class attribute and keep the reference alive for the image.
self.image = ImageTk.PhotoImage(image=Image.fromarray(random.random((50,50))))
您在这里可能没有注意到的第二个问题是,加载图像时不会显示您的文本。这是因为您需要添加参数compound
才能使tkinter在按钮中同时显示图像和文本。也就是说,您还需要更新image参数以包含新的self.image
。
所以改变这个:
b = Button(w, text="text", command=self.cb, image=image)
对此:
# added compound and change text color so you can see it.
b = Button(w, compound="center" , text="text", fg="white", command=self.cb, image=self.image)
结果:
答案 1 :(得分:1)
我想我了解发生了什么。由于链接的问题,第二种情况是,image
方法完成后,您的__init__
被垃圾回收了。结果,您的映像不再对根应用程序可用,因此无法将其绑定到该映像。
解决它的方法是使它成为一个类属性:
class A():
def __init__(self, w):
self.image = ImageTk.PhotoImage(image=Image.fromarray(random.random((50,50))))
b = Button(w, text="text", command=self.cb, image=self.image)
b.pack()
def cb(self):
print("Hello World")