【问题标题】:Tkinter program does not work correctly on first try, works as intended after restartTkinter 程序在第一次尝试时无法正常工作,重启后按预期工作
【发布时间】:2019-05-08 16:00:29
【问题描述】:

当我第一次启动该程序时,该程序中的 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,看起来它们注册正确,并且更新板也正确。

【问题讨论】:

    标签: python python-3.x oop tkinter tkinter-canvas


    【解决方案1】:

    游戏开始时画布/绑定配置不正确。我还没有真正深入研究您的代码以找出原因(有很多内容需要深入研究以获得简短的答案),但是当您第一次开始时,您的索引似乎落后了。这可以通过将 restart() 函数中的画布配置循环添加到代码块底部的游戏循环中来解决,如下所示:

    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')**
    

    注意:复制代码时实际上不要包含**。它只是为了强调。如果它不是代码块,它会被重新格式化为粗体,但不能同时格式化为 boldcode

    【讨论】:

    • 就是这样!谢谢。
    猜你喜欢
    • 1970-01-01
    • 2013-07-03
    • 2022-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    相关资源
    最近更新 更多