更改tkinter中使用for循环创建的按钮颜色

时间:2017-12-16 11:38:00

标签: python button tkinter

所以我使用for循环创建了5 x 5个按钮:

for i in range(5):
for j in range(5):
    gameButton = Button(boardFrame, bg="khaki1", width=10, height=5, command=colorTheButton)
    gameButton.grid(row=i, column=j, sticky=E)

我有一个名为changeColor()的函数:

def colorTheButton():
    global colorCounter, boardColor
    row = gameButton.grid_info()['row']
    column = gameButton.grid_info()['column']

    if colorCounter % 2 == 0:
        boardColor = "black"
    else:
        boardColor = "white"
    colorCounter += 1

    button = button(boardFrame, bg=boardColor, width=10, height=5)
    button.grid(row=row, column=column)

现在的问题是,每次点击任何按钮都不会改变点击按钮的颜色,它会改变最后创建的按钮的颜色。如何更改点击按钮而不是最后一个按钮?

2 个答案:

答案 0 :(得分:0)

for循环中,为每个新按钮指定相同名称gameButton。这意味着只有最新的按钮被保存到变量中,在这种情况下是右下角的按钮。

当您说row = gameButton.grid_info()['row']column = gameButton.grid_info()['column']时,这只会获得网格中的最后一个按钮位置。这意味着只有最后一个按钮会按照您的观察结果进行更新。

要解决此问题,您可以实现包含按钮的列表,或以其他方式实现。一个这样的方式是这样的:

for i in range(5):
    for j in range(5):
        gameButton = Button(boardFrame, bg="khaki1", width=10, height=5,
                            command=lambda i=i, j=j: colorTheButton(i, j))
        gameButton.grid(row=i, column=j, sticky=E)

我将命令更改为lambda i=i, j=j: colorTheButton(i, j),将按钮的实际网格位置传递给colorTheButton

然后colorTheButton如下:

def colorTheButton(row, column):
    global colorCounter, boardColor
    if colorCounter % 2 == 0:
        boardColor = "black"
    else:
        boardColor = "white"
    colorCounter += 1

    button = Button(boardFrame, bg=boardColor, width=10, height=5)
    button.grid(row=row, column=column)

请注意,我尽量保持您的代码尽可能相似;这段代码每次都会产生一个 new 按钮,将旧的按钮叠加到位。这不如修改原始按钮那么有效,但这是一个不同的问题!

答案 1 :(得分:0)

首先,你要创建多个按钮但是它们被覆盖分配给同一个变量gameButton,因此你只能 引用 last 按钮创建,稍后,这将是有问题的。

您可以改为创建按钮:

gameButton = list()
for i in range(5)
    gameButton.append(list())
    for j in range(5)
        gameButton[i].append(Button(boardFrame, bg="khaki1", width=10, height=5, command=colorTheButton))
        gameButton[i][j].grid(row=i, column=j, sticky=E)

其次,您应该将节点信息传递给colorTheButton方法,而不是试图找到稍后按下的按钮:

gameButton[i].append(Button(boardFrame, bg="khaki1", width=10, height=5, command=lambda row=i, col=j : colorTheButton(row, col))

相应地修改colorTheButton

def colorTheButton(row, column):
    global colorCounter, boardColor
    if colorCounter % 2 == 0:
...

注意:该函数的最后两行也会不断创建不可参考的按钮对象 小部件

好多了:

def colorTheButton(row, column):
    global colorCounter, boardColor
    if colorCounter % 2 == 0:
        boardColor = "black"
    else:
        boardColor = "white"
    colorCounter += 1

    gameButton[row][column]['bg'] = boardColor