如何使用tkinter(python)使每个按钮在单击时显示不同的图像

时间:2018-07-10 13:43:18

标签: python tkinter

我正在创建带有“ .grid”按钮的GUI。我想使这些按钮中的每一个在按下时显示不同的图像。因此,当我单击按钮1时,它将在按钮底部弹出“ image1” 。当我单击按钮2时,它将弹出“ image2” 等。

通过一些研究,我能够使按钮运行通过以下方法输入参数的功能。但是,我似乎无法使按钮显示图像。相反,当我按下任意按钮时,它只会在按钮下方留出空白。

免责声明:  -我不希望有大量图像,只会有1张图像,并且它会根据我按下的按钮而改变。

以下是代码:

from tkinter import *

def funct(numimg):
    image = PhotoImage(file="image"+str(numimg)+".png")   
    label = Label(image=image)
    label.grid(row = row_no+1, column = 0, columnspan = num_of_cols)

def make_funct(number):
    return (lambda: funct(number))

root= Tk()
row_no = -1
buttons = []
num_of_cols = 3
root.resizable(0, 0)
numfiles = 6

for x in range(0, numfiles):
    if(x % num_of_cols is 0):
        row_no+=1

    buttons.append(Button(root, text = "Button "+str(x), bg = '#4098D3', width = 30,height = 13,command = make_funct(x)))
    buttons[x].grid(row = row_no, column = x % num_of_cols)

root.mainloop()

所以我的问题是,如何制作每个单独的按钮,当按下按钮时显示不同的图像?此程序就在此处,在替换图像时只留下了空白区域,图片未显示。

1 个答案:

答案 0 :(得分:1)

您发布的代码有两个主要问题。

第一个基本上与此问题相同:Why does Tkinter image not show up if created in a function?。您应该保留对PhotoImage对象的引用,否则将对其进行垃圾收集并且不会显示。

第二个是您每次单击按钮都会创建一个新的Label。您只应制作一个Label并使用label.config()方法更改图像。

我会(不将您的GUI封装在类中,这可能是一个更好的解决方案)在初始化时加载所有图像,将它们保存在列表中作为标签的属性,并且仅在单击按钮时更改图像。

我还删除了make_funct函数,并将其替换为lambda,这是将变量传递给回调函数的最常用方法。

from tkinter import *

def funct(numimg):
    label.config(image=label.images[numimg])

root= Tk()
row_no = -1
buttons = []
num_of_cols = 3
root.resizable(0, 0)
numfiles = 3

for x in range(0, numfiles):
    if(x % num_of_cols is 0):
        row_no+=1

    buttons.append(Button(root, text = "Button "+str(x), bg = '#4098D3', width = 30,height = 13, command = lambda n=x: funct(n)))
    buttons[x].grid(row = row_no, column = x % num_of_cols)

label = Label(root)
label.grid(row = row_no+1, column = 0, columnspan = num_of_cols)

label.images=[]

for x in range(0, numfiles):
    label.images.append(PhotoImage(file="image"+str(x)+".png"))

root.mainloop()