Python ttk 按钮。将参数传递给 OnClick

Python ttk buttons. Passing args to OnClick

我是 Python 的新手,也完全不熟悉在此论坛上发帖(我已经使用它多年,但通常更幸运的是通过搜索过去的问题找到答案。我不过我今天被难住了)。

rows = 8
columns = 8

def onClick(args):
    print("args: ", args)

myButtons = []

myButtons = [ ttk.Button(mainframe, text=str(i) + str(j), command=lambda:onClick([int(i),int(j)])) for i in range(columns) for j in range(rows) ]

for i in range(columns) :
    for j in range(rows):
        myButtons[i*rows+j].grid(column=i, row=j)

(我没有包含所有网格创建代码,但它工作正常,按钮正在显示。)。

我正在尝试为网格中的按钮调用点击事件。我尝试创建具有不同参数的按钮,这些参数传递到 onClick 事件中,以便我知道单击了哪个按钮。我确信这在我单独创建按钮时有效,而不是在我使用列表理解创建按钮时有效。不过现在,无论我点击哪个按钮,我都会得到:

args: [7,7]

谁能指出我哪里出错了?

谢谢!

使用事件处理程序捕获 i 和 j 的小改动:

def on_click(args):
    print("args: ", args)


def click_handler(args):
    return lambda: on_click(args)


myButtons = [ttk.Button(mainframe, text=str(i) + str(j), command=lambda: click_handler([int(i),int(j)])) for i in range(8) for j in range(8)]

# for ...

您需要在 lambda:

中使用参数的默认值
myButtons = [ttk.Button(mainframe, text=str(i)+str(j), command=lambda i=i,j=j: onClick([i,j])) for i in range(columns) for j in range(rows)]

您也可以将列表理解和 for 循环结合在一起:

myButtons = []
for i in range(columns):
    for j in range(rows):
        btn = ttk.Button(mainframe, text=str(i)+str(j),
                        command=lambda i=i,j=j:onClick([i,j]))
        btn.grid(column=i, row=j)
        myButtons.append(btn)