我正在尝试学习如何使用Python中的tkinter进行GUI,并且我收到错误,我的回调函数未定义。基本上我想要一个白色方块网格,当你点击方块时它会变成红色。
from tkinter import *
root = Tk()
class Application(Frame):
def __init__(self, master, *args, **kwargs):
Frame.__init__(self, master, *args, ** kwargs)
self.createWidgets()
def mouse_click(self):
self.squares.bg = 'red'
def createWidgets(self):
for i in range(10):
for j in range(10):
self.squares = Button(self, height = 3, width = 7, bg = 'white',
command = lambda: mouse_click())
self.squares.grid(row = i, column = j)
Application(root).grid()
root.mainloop()
答案 0 :(得分:2)
您的代码中存在多个问题。
mouse_click
是一个实例方法,因此必须引用为self.mouse_click
。self.squares
,所以最后它会引用你创建的最后一个按钮。这没用,可以删除。解决此问题的简洁方法是重写mouse_click
方法以将按钮作为参数:
def mouse_click(self, square):
square['bg'] = 'red'
然后为每个按钮的command
函数提供对按钮本身的引用。这可以通过functools.partial
:
def createWidgets(self):
for i in range(10):
for j in range(10):
square = Button(self, height = 3, width = 7, bg = 'white')
square['command'] = functools.partial(self.mouse_click, square)
square.grid(row = i, column = j)
这使得按钮的click事件处理程序接收按钮作为参数。通过这两个更改,一切都按预期工作。
答案 1 :(得分:1)
您需要使用ommand = lambda: self.mouse_click()
。
然而,这并没有解决所有问题。另一个问题是你正在创建一个2D网格按钮,但只存储你班级中的最后一个按钮。
该行
self.squares = Button(...)
只存储一个按钮。您最终将句柄存储到最后Button
。您在之前的步骤中创建的其他Button
将丢失给您的班级。
这是我的建议(未经核实):
class Application(Frame):
def __init__(self, master, *args, **kwargs):
Frame.__init__(self, master, *args, ** kwargs)
self.createWidgets()
def mouse_click(self, i, j):
self.squares[i][j].bg = 'red'
def createWidgets(self):
# Creeate a 2D array that contains None in all the elements.
self.squares = [[None for x in range(10)] for y in range(10)]
# Fill up the array.
for i in range(10):
for j in range(10):
# Create a button and display it in the i-th row and j-th
# column in a grid.
button = Button(self,
height = 3,
width = 7,
bg = 'white',
command = lambda: self.mouse_click(i, j))
button.grid(row = i, column = j)
# Store the button for the callback function
self.squares[i][j] = button