Python 在单个tkinter按钮上绑定2个图像

Python 在单个tkinter按钮上绑定2个图像,python,tkinter,Python,Tkinter,我正在尝试制作一个应用程序,如果我左键单击网格中的一个按钮,它会将图像更改为1.jpg,右键单击时,它会更改为2.jpg。我试了好几次,但右键点击图片时没有改变 守则: from tkinter import * from PIL import ImageTk, Image WIN = Tk() WIN.geometry("280x660+300+10") Button_Frame = Frame(WIN,width=399,height=100) Button_Fram

我正在尝试制作一个应用程序,如果我左键单击网格中的一个按钮,它会将图像更改为
1.jpg
,右键单击时,它会更改为
2.jpg
。我试了好几次,但右键点击图片时没有改变

守则:

from tkinter import *
from PIL import ImageTk, Image

WIN = Tk()
WIN.geometry("280x660+300+10")

Button_Frame = Frame(WIN,width=399,height=100)
Button_Frame.pack()
Main = Frame(WIN,width=399,height=399)
Main.pack()

img1 = Image.open("2.jpg")
img1 = img1.resize((57, 57), Image.ANTIALIAS)
photo1 = ImageTk.PhotoImage(img1)

img2 = Image.open("3.jpg")
img2 = img2.resize((57, 57), Image.ANTIALIAS)
photo2 = ImageTk.PhotoImage(img2)

button_list = []
type_click = ""

for i in range(49):
   f1 = Frame(Main,width=40,height=40,bg="black")
   b = Button(f1, text = "",borderwidth=4,bg="white")
   button_list.append(b)

   def first(k):
       if type_click == "left":
           button_list[k].configure(image=photo1)
       elif type_click == "right":
           button_list[k].configure(image=photo2)

   def left(event):
       global type_click
       type_click = "left"
       print("left")
   def right(event):
       global type_click
       type_click = "right"    
       print("right")  

   b.configure(command=lambda k=i:first(k))
   b.bind("<Button-1>",left)
   b.bind("<Button-3>",right)
   f1.rowconfigure(0, weight = 1)
   f1.columnconfigure(0, weight = 1)
   f1.grid_propagate(0)
   f1.grid(row = i//7, column = i%7)


  # b.bind("<Button-1>",lambda k=i:first(k))
   b.grid(sticky = "NWSE")
   
WIN.mainloop()
从tkinter导入*
从PIL导入ImageTk,图像
WIN=Tk()
WIN.geometry(“280x660+300+10”)
按钮\框=框(赢,宽=399,高=100)
按钮\框架包()
主=框架(WIN,宽度=399,高度=399)
Main.pack()
img1=Image.open(“2.jpg”)
img1=img1.resize((57,57),Image.ANTIALIAS)
photo1=ImageTk.PhotoImage(img1)
img2=Image.open(“3.jpg”)
img2=img2.resize((57,57),Image.ANTIALIAS)
photo2=ImageTk.PhotoImage(img2)
按钮列表=[]
键入_click=“”
对于范围(49)内的i:
f1=框架(主框架,宽度=40,高度=40,bg=“黑色”)
b=按钮(f1,text=”“,borderwidth=4,bg=“白色”)
按钮列表。附加(b)
def优先(k):
如果类型\单击==“左”:
按钮列表[k]。配置(图像=1)
elif type_click==“right”:
按钮列表[k]。配置(图像=照片2)
def left(事件):
全局类型单击
键入\u click=“left”
打印(“左”)
def权限(事件):
全局类型单击
键入\u click=“right”
打印(“右”)
b、 配置(命令=lambda k=i:first(k))
b、 绑定(“,左)
b、 绑定(“,右)
f1.行配置(0,权重=1)
f1.列配置(0,权重=1)
f1.网格传播(0)
f1.网格(行=i//7,列=i%7)
#b.bind(“,λk=i:first(k))
b、 网格(sticky=“NWSE”)
WIN.mainloop()

请告诉我哪里出了问题

以下是我解决问题的方法,我制作了一个列表,并将每个按钮添加到列表中,然后我向下索引到列表中的当前项并使用其方法

buts = []
for i in range(49):
    f1 = Frame(Main,width=40,height=40,bg="black")
    buts.append(Button(f1,borderwidth=4,bg="white",command=lambda k=i:first(k)))
    buts[i].config(highlightbackground="black")

    f1.rowconfigure(0, weight = 1)
    f1.columnconfigure(0, weight = 1)
    f1.grid_propagate(0)
    f1.grid(row = i//7, column = i%7)
    buts[i].grid(sticky = "NWSE")
    buts[i].bind('<Button-3>',lambda e=None, i=i:second(e,i))
这样,代码应该以缩进的方式工作,而不是创建两个函数。您可以只使用一个函数并识别按键,然后相应地工作,但必须使用事件

但是我在代码中发现了一个问题,一旦右键单击它,按钮就不能用于左键单击。因此,为了解决这个问题,我还使用了另一个左键单击的
bind

buts[i].bind('<Button-1>',lambda e=None, i=i:first(e,i))
确保从按钮中删除
命令
参数

def first(k):
    global photo
    img = Image.open("img1.jpg")
    img = img.resize((19, 19), Image.ANTIALIAS) 
    photo = ImageTk.PhotoImage(img) 
    buts[k].configure(image=photo)

def second(event,i):
    global photo1
    img = Image.open("img2.jpg")
    img = img.resize((19, 19), Image.ANTIALIAS) 
    photo1 = ImageTk.PhotoImage(img) 
    buts[i].configure(image=photo1)
最终代码:

from tkinter import *
from PIL import ImageTk, Image

WIN = Tk()
WIN.geometry("280x660+300+10")

Button_Frame = Frame(WIN,width=399,height=100)
Button_Frame.pack()
Main = Frame(WIN,width=399,height=399)
Main.pack()

def first(event,k):
    global photo
    img = Image.open("img1.jpg")
    img = img.resize((19, 19), Image.ANTIALIAS) 
    photo = ImageTk.PhotoImage(img) 
    buts[k].configure(image=photo)

def second(event,i):
    global photo1
    img = Image.open("img2.jpg")
    img = img.resize((19, 19), Image.ANTIALIAS) 
    photo1 = ImageTk.PhotoImage(img) 
    buts[i].configure(image=photo1)

buts = []
for i in range(49):
    f1 = Frame(Main,width=40,height=40,bg="black")
    buts.append(Button(f1,borderwidth=4,bg="white"))
    buts[i].config(highlightbackground="black")

    f1.rowconfigure(0, weight = 1)
    f1.columnconfigure(0, weight = 1)
    f1.grid_propagate(0)
    f1.grid(row = i//7, column = i%7)
    buts[i].grid(sticky = "NWSE")
    buts[i].bind('<Button-3>',lambda e=None, i=i:second(e,i))
    buts[i].bind('<Button-1>',lambda e=None, i=i:first(e,i))

WIN.mainloop()
从tkinter导入*
从PIL导入ImageTk,图像
WIN=Tk()
WIN.geometry(“280x660+300+10”)
按钮\框=框(赢,宽=399,高=100)
按钮\框架包()
主=框架(WIN,宽度=399,高度=399)
Main.pack()
def first(事件,k):
全球照片
img=Image.open(“img1.jpg”)
img=img.resize((19,19),Image.antialas)
photo=ImageTk.PhotoImage(img)
但是[k]。配置(图像=照片)
def秒(事件,i):
全球摄影1
img=Image.open(“img2.jpg”)
img=img.resize((19,19),Image.antialas)
photo1=ImageTk.PhotoImage(img)
但是[i]。配置(image=photo1)
但是=[]
对于范围(49)内的i:
f1=框架(主框架,宽度=40,高度=40,bg=“黑色”)
但是追加(按钮(f1,borderwidth=4,bg=“白色”))
但是[i].config(highlightbackground=“black”)
f1.行配置(0,权重=1)
f1.列配置(0,权重=1)
f1.网格传播(0)
f1.网格(行=i//7,列=i%7)
但是[i]。网格(sticky=“NWSE”)
但是[i].bind(“”,lambda e=None,i=i:second(e,i))
但是[i].bind(“”,lambda e=None,i=i:first(e,i))
WIN.mainloop()

只需在继续单击“新建块”的同时查找每个图像,然后创建一个新列表
ref
然后
ref.append(photo)
,去掉
global photo
,并对其他功能执行相同操作。这里的目标只是保留对图像的引用,这样它就不会被垃圾收集。

下面是我如何解决这个问题的,我制作了一个列表,并将每个按钮附加到列表中,然后我索引到列表中的当前项并使用其方法

buts = []
for i in range(49):
    f1 = Frame(Main,width=40,height=40,bg="black")
    buts.append(Button(f1,borderwidth=4,bg="white",command=lambda k=i:first(k)))
    buts[i].config(highlightbackground="black")

    f1.rowconfigure(0, weight = 1)
    f1.columnconfigure(0, weight = 1)
    f1.grid_propagate(0)
    f1.grid(row = i//7, column = i%7)
    buts[i].grid(sticky = "NWSE")
    buts[i].bind('<Button-3>',lambda e=None, i=i:second(e,i))
这样,代码应该以缩进的方式工作,而不是创建两个函数。您可以只使用一个函数并识别按键,然后相应地工作,但必须使用事件

但是我在代码中发现了一个问题,一旦右键单击它,按钮就不能用于左键单击。因此,为了解决这个问题,我还使用了另一个左键单击的
bind

buts[i].bind('<Button-1>',lambda e=None, i=i:first(e,i))
确保从按钮中删除
命令
参数

def first(k):
    global photo
    img = Image.open("img1.jpg")
    img = img.resize((19, 19), Image.ANTIALIAS) 
    photo = ImageTk.PhotoImage(img) 
    buts[k].configure(image=photo)

def second(event,i):
    global photo1
    img = Image.open("img2.jpg")
    img = img.resize((19, 19), Image.ANTIALIAS) 
    photo1 = ImageTk.PhotoImage(img) 
    buts[i].configure(image=photo1)
最终代码:

from tkinter import *
from PIL import ImageTk, Image

WIN = Tk()
WIN.geometry("280x660+300+10")

Button_Frame = Frame(WIN,width=399,height=100)
Button_Frame.pack()
Main = Frame(WIN,width=399,height=399)
Main.pack()

def first(event,k):
    global photo
    img = Image.open("img1.jpg")
    img = img.resize((19, 19), Image.ANTIALIAS) 
    photo = ImageTk.PhotoImage(img) 
    buts[k].configure(image=photo)

def second(event,i):
    global photo1
    img = Image.open("img2.jpg")
    img = img.resize((19, 19), Image.ANTIALIAS) 
    photo1 = ImageTk.PhotoImage(img) 
    buts[i].configure(image=photo1)

buts = []
for i in range(49):
    f1 = Frame(Main,width=40,height=40,bg="black")
    buts.append(Button(f1,borderwidth=4,bg="white"))
    buts[i].config(highlightbackground="black")

    f1.rowconfigure(0, weight = 1)
    f1.columnconfigure(0, weight = 1)
    f1.grid_propagate(0)
    f1.grid(row = i//7, column = i%7)
    buts[i].grid(sticky = "NWSE")
    buts[i].bind('<Button-3>',lambda e=None, i=i:second(e,i))
    buts[i].bind('<Button-1>',lambda e=None, i=i:first(e,i))

WIN.mainloop()
从tkinter导入*
从PIL导入ImageTk,图像
WIN=Tk()
WIN.geometry(“280x660+300+10”)
按钮\框=框(赢,宽=399,高=100)
按钮\框架包()
主=框架(WIN,宽度=399,高度=399)
Main.pack()
def first(事件,k):
全球照片
img=Image.open(“img1.jpg”)
img=img.resize((19,19),Image.antialas)
photo=ImageTk.PhotoImage(img)
但是[k]。配置(图像=照片)
def秒(事件,i):
全球摄影1
img=Image.open(“img2.jpg”)
img=img.resize((19,19),Image.antialas)
photo1=ImageTk.PhotoImage(img)
但是[i]。配置(image=photo1)
但是=[]
对于范围(49)内的i:
f1=框架(主框架,宽度=40,高度=40,bg=“黑色”)
但是追加(按钮(f1,borderwidth=4,bg=“白色”))
但是[i].config(highlightbackground=“black”)
f1.行配置(0,权重=1)
f1.列配置(0,权重=1)
f1.网格传播(0)
f1.网格(行=i//7,列=i%7)
但是[i]。网格(sticky=“NWSE”)
但是[i].bind(“”,lambda e=None,i=i:second(e,i))
但是[i].bind(“”,lambda e=None,i=i:first(e,i))
WIN.mainloop()

只需在继续单击“新建块”的同时查找每个图像,然后创建一个新列表
ref
然后
ref.append(photo)
,去掉
global photo
,并对其他功能执行相同操作。这里的目标只是保留对映像的引用,这样它就不会被垃圾收集。

您没有在
的回调中更改映像。虽然你也没有改变里面的形象