我正在创建一个按钮的tic-tac-toe板。单击时,每个按钮应交替切换到X或O.我已经在for循环中创建了按钮,并且如果可能的话,会避免单独初始化它们。 我已经尝试使用lambda将按钮传递给函数,并且我已经尝试通过调用self.bttn按钮来消除命令中的参数问题(因为这都发生在我修改的Frame类中)。但是,在这两种情况下,我遇到的问题是,无论我点击哪9个按钮,for循环创建的最终按钮都会响应。
def __build_board(self):
""" Creates tic-tac-toe board of 9 blank buttons. """
for row_num in range(3):
for col_num in range(3):
self.bttn = Button(self, text = " ", command = self.__change_button)
self.bttn.grid(row = row_num + 1, column = col_num, sticky = W)
这就是我用self.bttn尝试的方式。 self .__ change_button只是将self.bttn中的文本切换为X或O. 这就是我用lambda尝试它的方式......
def __build_board(self):
""" Creates tic-tac-toe board of 9 blank buttons. """
for row_num in range(3):
for col_num in range(3):
bttn = Button(self, text = " ", command = lambda: self.__change_button(bttn))
bttn.grid(row = row_num + 1, column = col_num, sticky = W)
我想我理解为什么这些方法不起作用。看起来,我已经命令所有的按钮来改变最后一个按钮的文本,但是我不知道如何让他们按照我想要的方式改变他们自己的文本。任何帮助将不胜感激。
答案 0 :(得分:0)
这是一个棘手的问题......
原因是lambda
将绑定到bttn
变量,而不是其值,因此所有按钮都会作用于最后一个按钮(因为将是循环之后变量的值。
要考虑到这一点:
x = 1
y = lambda : x
print(y()) # will print 1
x = 2
print(y()) # will print 2; lambda captures variables, not values
可能的解决方法是:
def __build_board(self):
""" Creates tic-tac-toe board of 9 blank buttons. """
for row_num in range(3):
for col_num in range(3):
def mkbutton():
b = Button(self, text = " ",
command = lambda: self.__change_button(b))
return b
bttn = mkbutton()
bttn.grid(row = row_num + 1, column = col_num, sticky = W)
这样每个lambda
都会绑定到自己独立的变量b
。
通常情况下,使用频繁模式可以更轻松地解决这类问题:
x = lambda y=y: ...
其中值y
被复制为lambda的可选参数的默认值。
但是,在您的情况下,这种方法是不可能的,因为在评估lambda
时,Button
实例尚未存在(因此您无法将其作为默认参数值存储在lambda本身。)