Tkinter 程序在第一次尝试时无法正常工作,重新启动后按预期工作
Tkinter program does not work correctly on first try, works as intended after restart
当我第一次启动该程序时,该程序中的 GUI 磁贴无法正常工作,但在我按下重新启动按钮后它们似乎可以正常工作。问题似乎是 find_closest()
在启动时没有选择正确的方块,但在 play()
方法中重新启动后似乎可以正常工作。
def play(self, event):
"""
user performs a move
calls computer move directly after if game not over
"""
selected_square = self.canvas.find_closest(event.x, event.y)
我试过将 board
移动为实例变量,但这并没有解决问题。
这里是__init__
方法:
class Game(object):
'''
GUI Tic-tac-toe game.
Argument:
parent (tkinter.Tk): the root window object
Attributes:
canvas = (tkinter.Canvas) widget defining game board
game_over = (bool) game state, game over = False, game ongoing = True
moves = (int) number of moves taken by both user and computer
label = (tkinter.Label) shows win/loss/draw message
'''
# Add your class variables if needed here - square size, etc...)
board = [[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]
MAX_MOVES = 9
def __init__(self, parent):
self.parent = parent
parent.title('Tic Tac Toe')
# Create the restart button widget
restart_button = tkinter.Button(self.parent, text='RESTART', width=20,
command=self.restart)
restart_button.pack()
# Create a canvas widget
self.canvas = tkinter.Canvas(parent, background='white', width=300,
height=300)
self.canvas.create_rectangle(0, 0, 300, 300)
self.canvas.create_rectangle(0, 0, 100, 100)
self.canvas.create_rectangle(100, 0, 200, 100)
self.canvas.create_rectangle(200, 0, 300, 100)
self.canvas.create_rectangle(0, 100, 100, 200)
self.canvas.create_rectangle(100, 100, 200, 200)
self.canvas.create_rectangle(200, 100, 300, 200)
self.canvas.create_rectangle(0, 200, 100, 300)
self.canvas.create_rectangle(100, 200, 200, 300)
self.canvas.create_rectangle(200, 200, 300, 300)
self.canvas.pack()
self.label = tkinter.Label(self.parent, text="")
self.label.pack()
self.game_over = False
if not self.game_over:
self.canvas.bind("<Button-1>", self.play)
self.moves = 0
重启方法如下:
def restart(self):
"""
resets game to beginning state
label erased, game tiles turned back white, button-1 rebound, moves set
to zero
"""
for square in self.canvas.find_all():
self.canvas.itemconfigure(square, fill='white')
self.board = [[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]
self.moves = 0
self.game_over = False
self.canvas.bind("<Button-1>", self.play)
self.label.config(text="")
其余代码可以找到here。
我试过打印 event.x 和 event.y,它们似乎正确注册并正确更新了开发板。
canvas/bindings 游戏开始时配置不正确。我还没有真正挖掘你的代码来找出原因(有很多东西可以挖掘一个简短的答案),但是当你第一次开始时你的指数似乎落后了。这可以通过将 restart()
函数中的 canvas 配置循环添加到代码块底部的游戏循环来解决,如下所示:
def main():
root = tkinter.Tk()
gen_game = Game(root)
**for square in gen_game.canvas.find_all():**
**gen_game.canvas.itemconfigure(square, fill='white')**
root.mainloop()
或者将其添加到__init__
函数的底部,如下所示:
def __init__(self, parent):
self.parent = parent
parent.title('Tic Tac Toe')
# Create the restart button widget
restart_button = tkinter.Button(self.parent, text='RESTART', width=20,
command=self.restart)
restart_button.pack()
# Create a canvas widget
self.canvas = tkinter.Canvas(parent, background='white', width=300,
height=300)
self.canvas.create_rectangle(0, 0, 300, 300)
self.canvas.create_rectangle(0, 0, 100, 100)
self.canvas.create_rectangle(100, 0, 200, 100)
self.canvas.create_rectangle(200, 0, 300, 100)
self.canvas.create_rectangle(0, 100, 100, 200)
self.canvas.create_rectangle(100, 100, 200, 200)
self.canvas.create_rectangle(200, 100, 300, 200)
self.canvas.create_rectangle(0, 200, 100, 300)
self.canvas.create_rectangle(100, 200, 200, 300)
self.canvas.create_rectangle(200, 200, 300, 300)
self.canvas.pack()
self.label = tkinter.Label(self.parent, text="")
self.label.pack()
self.game_over = False
if not self.game_over:
self.canvas.bind("<Button-1>", self.play)
self.moves = 0
**for square in self.canvas.find_all():**
**self.canvas.itemconfigure(square, fill='white')**
注意:复制代码时实际上不要包含 **
。它只是为了强调。如果它不是代码块,它会被重新格式化为粗体,但它不能同时被格式化为 bold 和 code
.
当我第一次启动该程序时,该程序中的 GUI 磁贴无法正常工作,但在我按下重新启动按钮后它们似乎可以正常工作。问题似乎是 find_closest()
在启动时没有选择正确的方块,但在 play()
方法中重新启动后似乎可以正常工作。
def play(self, event):
"""
user performs a move
calls computer move directly after if game not over
"""
selected_square = self.canvas.find_closest(event.x, event.y)
我试过将 board
移动为实例变量,但这并没有解决问题。
这里是__init__
方法:
class Game(object):
'''
GUI Tic-tac-toe game.
Argument:
parent (tkinter.Tk): the root window object
Attributes:
canvas = (tkinter.Canvas) widget defining game board
game_over = (bool) game state, game over = False, game ongoing = True
moves = (int) number of moves taken by both user and computer
label = (tkinter.Label) shows win/loss/draw message
'''
# Add your class variables if needed here - square size, etc...)
board = [[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]
MAX_MOVES = 9
def __init__(self, parent):
self.parent = parent
parent.title('Tic Tac Toe')
# Create the restart button widget
restart_button = tkinter.Button(self.parent, text='RESTART', width=20,
command=self.restart)
restart_button.pack()
# Create a canvas widget
self.canvas = tkinter.Canvas(parent, background='white', width=300,
height=300)
self.canvas.create_rectangle(0, 0, 300, 300)
self.canvas.create_rectangle(0, 0, 100, 100)
self.canvas.create_rectangle(100, 0, 200, 100)
self.canvas.create_rectangle(200, 0, 300, 100)
self.canvas.create_rectangle(0, 100, 100, 200)
self.canvas.create_rectangle(100, 100, 200, 200)
self.canvas.create_rectangle(200, 100, 300, 200)
self.canvas.create_rectangle(0, 200, 100, 300)
self.canvas.create_rectangle(100, 200, 200, 300)
self.canvas.create_rectangle(200, 200, 300, 300)
self.canvas.pack()
self.label = tkinter.Label(self.parent, text="")
self.label.pack()
self.game_over = False
if not self.game_over:
self.canvas.bind("<Button-1>", self.play)
self.moves = 0
重启方法如下:
def restart(self):
"""
resets game to beginning state
label erased, game tiles turned back white, button-1 rebound, moves set
to zero
"""
for square in self.canvas.find_all():
self.canvas.itemconfigure(square, fill='white')
self.board = [[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]
self.moves = 0
self.game_over = False
self.canvas.bind("<Button-1>", self.play)
self.label.config(text="")
其余代码可以找到here。
我试过打印 event.x 和 event.y,它们似乎正确注册并正确更新了开发板。
canvas/bindings 游戏开始时配置不正确。我还没有真正挖掘你的代码来找出原因(有很多东西可以挖掘一个简短的答案),但是当你第一次开始时你的指数似乎落后了。这可以通过将 restart()
函数中的 canvas 配置循环添加到代码块底部的游戏循环来解决,如下所示:
def main():
root = tkinter.Tk()
gen_game = Game(root)
**for square in gen_game.canvas.find_all():**
**gen_game.canvas.itemconfigure(square, fill='white')**
root.mainloop()
或者将其添加到__init__
函数的底部,如下所示:
def __init__(self, parent):
self.parent = parent
parent.title('Tic Tac Toe')
# Create the restart button widget
restart_button = tkinter.Button(self.parent, text='RESTART', width=20,
command=self.restart)
restart_button.pack()
# Create a canvas widget
self.canvas = tkinter.Canvas(parent, background='white', width=300,
height=300)
self.canvas.create_rectangle(0, 0, 300, 300)
self.canvas.create_rectangle(0, 0, 100, 100)
self.canvas.create_rectangle(100, 0, 200, 100)
self.canvas.create_rectangle(200, 0, 300, 100)
self.canvas.create_rectangle(0, 100, 100, 200)
self.canvas.create_rectangle(100, 100, 200, 200)
self.canvas.create_rectangle(200, 100, 300, 200)
self.canvas.create_rectangle(0, 200, 100, 300)
self.canvas.create_rectangle(100, 200, 200, 300)
self.canvas.create_rectangle(200, 200, 300, 300)
self.canvas.pack()
self.label = tkinter.Label(self.parent, text="")
self.label.pack()
self.game_over = False
if not self.game_over:
self.canvas.bind("<Button-1>", self.play)
self.moves = 0
**for square in self.canvas.find_all():**
**self.canvas.itemconfigure(square, fill='white')**
注意:复制代码时实际上不要包含 **
。它只是为了强调。如果它不是代码块,它会被重新格式化为粗体,但它不能同时被格式化为 bold 和 code
.