如何使用其网格位置作为参数调用的函数在Tk中创建按钮网格

时间:2017-03-15 10:56:19

标签: python for-loop tkinter

我试图使用Tkinter创建一个简单的游戏板,其中的按钮会改变2D阵列中的单个项目,这与其在窗口中的位置相对应 - 因此我可以检查游戏是否结束通过检查数组。这是我的代码:

from tkinter import *
root = Tk()
board = []
for x in range(8):
    board.append([0,0,0,0,0,0,0,0])
def toggle(row,column):
    global board
    board[row][column] = (board[row][column]+1)%2
    print("-"*10)
    for x in board:
        for y in x:
            print(y, end="")
        print("")
    print("-"*10)
for x in range(8):
    for y in range(8):
        button = Button(master=root, text="--", command=lambda:toggle(y,x))
        button.grid(row=y,column=x)
root.mainloop()

然而,这只是给所有按钮命令切换(7,7),它们都只是切换最终项目的最终项目。我尝试了一个老问题,但我认为它是python2,因为解决方案没有改变我的代码。

2 个答案:

答案 0 :(得分:1)

作为Bryan Oakley"How to get grid information from pressed Button in tkinter?"的答案,所提供的来源缺少某些内容。

声明附加到每个按钮的command时,lambda必须在参数y,x和网格参数row=y,column=x之间建立链接:

    button = Button(master=root, text=xy_text,
        command=lambda row=x, column=y: toggle(row, column))
    button.grid(row=y,column=x)

答案 1 :(得分:0)

快速解决方法是:

def create_toggle_callback(y, x):
    return lambda: toggle(y, x)

并将按钮命令设置为:

button = Button(master=root, text="--", command=create_toggle_callback(y, x))

原因是变量作用域在python中用于闭包的方式。例如,请参阅this question。基本上我们需要在定义lambda时捕获值,而不是捕获对变量的引用。