我一直在写一段Tkinter代码,生成一系列按钮。每个按钮调用相同的功能。该函数(button_press)应该打印单击它的按钮。我应该输入什么代码来使button_press打印按下按钮的按钮?
我听说Lambda是有帮助的,但是我不确定该怎么做。
import tkinter as tk
import random
class App(tk.Frame):
def __init__(self, master = None):
super().__init__(master)
self.grid()
self.create_buttons()
self.create_mines()
def create_buttons(self):
self.buttons = []
for y in range(16):
self.buttons.append([])
for x in range(30):
self.buttons[y].append(x)
self.buttons[y][x] = tk.Button(command = self.button_press)
self.buttons[y][x].grid(column = str(x), row = str(y))
def create_mines(self):
self.mine_list = []
for mines in range(99):
self.yValue = random.randint(0, 15)
self.xValue = random.randint(0, 29)
if self.buttons[self.yValue][self.xValue] in self.mine_list:
mines += 1
else:
self.mine_list.append(self.buttons[self.yValue][self.xValue])
def button_press(self):
#?????
root = tk.Tk()
app = App(master = root)
app.mainloop()
答案 0 :(得分:1)
要使函数button_press
能够打印单击它的按钮,您需要将该按钮作为变量传递。
因此,button_press
的函数定义应该类似于
def button_press(self, x, y):
print("Button (%d,%d)" % (x,y))
创建按钮时,您可以执行类似的操作
self.buttons[y][x] = tx.Button(command = (lambda : self.button_press(x,y)))
这意味着单击按钮时,它会调用lambda函数,该函数使用按钮的x和y调用button_press。 Lambda很酷,绝对值得阅读更多。
答案 1 :(得分:1)
事件处理程序得到一个参数,一个事件,它具有多个属性,包括捕获该事件的小部件。不幸的是,命令功能没有参数,甚至没有捕获单击调用命令的小部件。
因此,如果您希望不同按钮的命令功能执行不同的操作,则必须传递不同的功能。在这种情况下,您需要30 x 16 = 480种不同的功能。替换
self.buttons[y][x] = tk.Button(command = self.button_press)
例如,
self.buttons[y][x] = tk.Button(
command=lambda x=x, y=y: print(f'{x},{y}'))
这是为每个按钮创建不同功能的多种方法之一。这是对该问题的常规答案。
另一种选择是不使用按钮命令选项,而是将按钮单击绑定到处理程序,该处理程序将获得包含单击按钮的事件。然后将有关单击处理程序所需的每个按钮的信息添加到每个按钮,而不是命令功能。这是游戏的完整开发版本,可供测试。
import tkinter as tk
import random
class App(tk.Frame):
def __init__(self, master, rows, columns):
self.master = master
self.rows = rows
self.columns = columns
super().__init__(master)
self.grid()
self.create_buttons()
self.create_mines()
def create_buttons(self):
self.buttons = []
for y in range(self.rows):
self.buttons.append([])
for x in range(self.columns):
button = tk.Button()
button.y = y
button.x = x
button.mine = False
button.grid(column=x, row=y)
button.bind('<Button-1>', self.button_press)
self.buttons[y].append(button)
def create_mines(self):
self.mines = set()
mine_num = 0
while mine_num < self.rows * self.columns // 5:
x = random.randint(0, self.columns-1)
y = random.randint(0, self.rows-1)
button = self.buttons[y][x]
if button not in self.mines:
button.mine = True
button['background'] = 'red'
self.mines.add(button)
mine_num += 1
def button_press(self, event):
b = event.widget
label = 'Mine' if b.mine else 'Free'
print(f'{label} {b.x}-{b.y}')
root = tk.Tk()
app = App(root, rows=16, columns=30)
app.mainloop()
对于游戏,单击时显示地雷,而不是在创建时显示; 0)。
答案 2 :(得分:0)
答案竟然是按钮绑定(感谢@pstatix)!
添加
self.buttons[y][x].bind('<Button-1>', self.button_press)
之后
self.buttons[y][x].grid(column = str(x), row = str(y))
更改
def button_press(self):
到
def button_press(self, event):
print(event.widget)
并将其移至上方
def create_buttons(self)