-1

这些按钮是在一个更大的循环中创建的,通过以下代码迭代 i 然后 j:

btn[i][j] = Button(lbl_frm, width=24, height=24, image=unchecked_img,
                                       command=lamda:change_btn_img(btn[i][j]),relief=SOLID)

                global state
                state = "unchecked"

                btn[i][j].place(relx=.5, rely=.5, anchor='c')

具有更改按钮配置的功能:

def change_btn_img(btn):
    global state
    if state == "checked":
        btn.configure(image=unchecked_img)
        state = "unchecked"

    elif state == "unchecked":
        btn.configure(image=checked_img)
        state = "checked"

但是,这不起作用,就像我单击任何按钮一样,它只会更改 btn[i][j] 的图像,其中 i 和 j 是在循环的最后一次迭代中达到的值。这些按钮用于形成一个网格,在这种情况下,单击任何按钮都会更改最后一行中的最后一个元素。有什么方法可以使在创建按钮时声明命令时使用的 i 和 j 固定到该特定按钮?

4

1 回答 1

0

lambda这是in的常见问题loop

您必须将i,分配给(即, )j中的参数,它会从 中复制值,而不是使用对,的引用lambdaxyijij

 command=lamda x=i, y=j:change_btn_img(btn[x][y]) 

顺便提一句:

在 Python 中,您可以在类中创建自己的属性,所以也许您应该state保留Button

 btn[i][j].state = "unchecked"

然后你就不需要global了,每个按钮都有自己的state


或者也许你应该创建自己的Widget- 像这样:

class MyButton(tkinter.Button):

    def __init__(self, parent, *args, **kwars):
        super().__init__(parent, width=24, height=24, image=unchecked_img, command=self.change, relief=tkitner.SOLID)
        self.state = "unchecked"
        
    def change(self):
        if self.state == "checked":
            self.configure(image=unchecked_img)
            self.state = "unchecked"
        elif self.state == "unchecked":
            self.configure(image=checked_img)
            self.state = "checked"
            

后来你可以简单地使用

btn[i][j] = MyButton(lbl_frm)

btn[i][j].place(relx=.5, rely=.5, anchor='c')
于 2021-02-10T03:18:47.253 回答