这个问题在这里已有答案:
我正在创建一个简单的TicTacToe GUI。这是我到目前为止所得到的:
import tkinter as tk
def initTable(master, rows, columns):
for i in range(0, columns):
button = tk.Button(master, text="", height=1, width=2)
button.grid(row=i)
for j in range(0, rows):
button2 = tk.Button(master, text="", height=1, width=2)
button2.grid(row=i, column=j)
if "__main__" == __name__:
print("Welcome to the TicTacToe game!")
print("Recommended size: 10x10")
correctinput = False
while True:
if correctinput:
print("The entered size is too big, please enter a smaller value")
height = int(input("Please enter the height (Max. 70)!"))
width = int(input("Please enter the width (Max. 70)!"))
correctinput = True
if height <= 70 and width <= 70: # This check is needed because it seems that you can't use any bigger
# table than this, it will freeze the computer...
break
master = tk.Tk()
master.resizable(width=False, height=False)
initTable(master, height, width)
master.mainloop()
因此,这将创建具有用户指定的宽度和高度的GUI。但是,现在我想管理这些单独创建的按钮。例如,如果在GUI中创建的按钮上按下鼠标左键,则应在该标签中显示X.我找到了这些来显示它:
def leftclick(event):
print("leftclick")
def rightclick(event):
print("rightclick")
button.bind('<Button-1>', leftclick)
button.bind('<Button-3>', rightclick)
但是我不知道如何使用它,因为按钮没有唯一的名称等等...也许用winfo_child()?
你要做的第一件事是修复你的initTable
功能。如果仔细观察一下,你会发现它创建了太多按钮:
def initTable(master, rows, columns):
for i in range(0, columns):
button = tk.Button(master, text="", height=1, width=2)
button.grid(row=i)
# ^ we don't need that button
for j in range(0, rows):
button2 = tk.Button(master, text="", height=1, width=2)
button2.grid(row=i, column=j)
嵌套循环实际上是在彼此的顶部创建两个分层按钮。正确的代码仅在内部循环中创建按钮:
def initTable(master, rows, columns):
for i in range(0, columns):
for j in range(0, rows):
button = tk.Button(master, text="", height=1, width=2)
button.grid(row=i, column=j)
当你在它的时候,你也应该将leftclick
和rightclick
函数连接到创建的每个按钮:
def initTable(master, rows, columns):
for i in range(0, columns):
for j in range(0, rows):
button = tk.Button(master, text="", height=1, width=2)
button.grid(row=i, column=j)
button.bind('<Button-1>', leftclick)
button.bind('<Button-3>', rightclick)
回调函数可以访问通过event.widget
属性触发事件的按钮,因此实现很简单:
def leftclick(event):
mark_button(event.widget, 'X')
def rightclick(event):
mark_button(event.widget, 'O')
def mark_button(button, mark):
# if the button has already been clicked, do nothing
if button['text']:
return
button['text'] = mark