tkinter>>如何获得按钮引用?

时间:2014-01-17 18:33:12

标签: python button tkinter

我目前正在尝试使用Python和tkinter创建一个战舰游戏。 我需要声明100个按钮(玩家可以触发每个点的一个按钮),并且我发现我可以这样做以将它们放入10x10网格中,同时还使用变量buttons_dict存储对它们的引用

from tkinter import *
from tkinter import ttk

root = Tk()
board_frame = ttk.Frame(root, padding=5)
board_frame.grid(column=0,row=0)

COORDS_LIST = []
buttons_dict = {}

for r in range(1,11):
    for c in range(1,11):
        coord = str(r)+"_"+str(c)
        COORDS_LIST.append(coord)
        buttons_dict[COORDS_LIST[-1]] = ttk.Button(board_frame, text="O", width="2")
        buttons_dict[COORDS_LIST[-1]].grid(row=r,column=c)

root.mainloop()

此代码创建100个按钮,完全按照我的需要显示。当我想给每个人发一个命令时,问题就开始了。我想要的是一个通用函数(我们可以称之为'fire_here'来解决这个问题),每次按下一个按钮时都会调用它,但我需要传递1或2个参数: 它可以是创建该按钮时附加到COORDS_LIST的值,也可以是按钮的“列”和“行”值。 那么我该怎么做呢?如何放置一个按钮的行/列?

1 个答案:

答案 0 :(得分:1)

我想你想要这样的东西:

from tkinter import *
from tkinter import ttk

root = Tk()
board_frame = ttk.Frame(root, padding=5)
board_frame.grid(column=0,row=0)

COORDS_LIST = []
buttons_dict = {}

###########################################
def fire_here(x, y):
    print("column:{}, row:{}".format(x, y))
###########################################

for r in range(1,11):
    for c in range(1,11):
        coord = str(r)+"_"+str(c)
        COORDS_LIST.append(coord)
        buttons_dict[COORDS_LIST[-1]] = ttk.Button(board_frame, text="O", width="2")
        ###########################################################################
        buttons_dict[COORDS_LIST[-1]]["command"] = lambda x=c, y=r: fire_here(x, y)
        ###########################################################################
        buttons_dict[COORDS_LIST[-1]].grid(row=r,column=c)

root.mainloop()

我添加的所有内容都在评论框中。然而,重要的是这个:

buttons_dict[COORDS_LIST[-1]]["command"] = lambda x=c, y=r: fire_here(x, y)

基本上,它做了两件事:

  1. 使用lambda,它会为当前按钮的command选项创建一个函数。单击按钮时将调用此函数。

  2. 它采用当前列和行(网格上的按钮坐标)并将它们设置为函数的xy参数的默认值。此外,当调用该函数时,这些值将被发送到fire_here进行处理。


  3. 另外,你可以把它放在上面这样的行:

    buttons_dict[COORDS_LIST[-1]] = ttk.Button(board_frame, text="O", width="2", command=lambda x=c, y=r: fire_here(x, y))
    

    但是,我把它放在自己的路线上以提高代码的清晰度。