Tkinter和Tic-Tac-T的麻烦

2024-10-01 22:41:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我在用Tkinter写一个Tic-Tac-Toe游戏。当一个用户赢了,一个顶层窗口出现与重新启动按钮,必须重新启动程序,但我收到意外的错误,当我点击它。我知道我的获奖者检查功能是愚蠢的,但我可以写一个更好的以我目前的知识水平。 错误消息:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Eldiiar Raiymkulov\AppData\Local\Programs\Python\Python36-32\lib\tkinter\__init__.py", line 1699, in __call__
    return self.func(*args)
  File "C:\Users\Eldiiar Raiymkulov\Desktop\xo2.py", line 62, in <lambda>
    command=lambda x=x, y=y: clicked(y, x)))
  File "C:\Users\Eldiiar Raiymkulov\Desktop\xo2.py", line 15, in clicked
    isWinner(char)
  File "C:\Users\Eldiiar Raiymkulov\Desktop\xo2.py", line 46, in isWinner
    topMessage(char)
  File "C:\Users\Eldiiar Raiymkulov\Desktop\xo2.py", line 30, in topMessage
    topButton = Button(top, text="Restart", command=restart(root))
NameError: name 'root' is not defined

代码如下:

from tkinter import *

turn = True
btns = None
def clicked(y, x):
    global turn, btns
    char = ""
    if turn:
        char = "X"
    else:
        char = "O"

    btns[y][x].config(text=char,
                      state=DISABLED)
    isWinner(char)
    turn = not turn

def restart(root):
    global turn
    turn = True
    root.destroy()
    main()
def topMessage(char):
    global root
    top = Toplevel()
    top.title("Congratulations!")
    topText = Label(top, text=f"{char} is a winner!")
    topButton = Button(top, text="Restart", command=restart(root))
    topText.grid(row=0)
    topButton.grid(row=1)
def isWinner(char):
    global root
        #horizontal
    if (((btns[1][1].cget("text") == char) and (btns[1][2].cget("text") == char) and (btns[1][3].cget("text") == char)) or
    ((btns[2][1].cget("text") == char) and (btns[2][2].cget("text") == char) and (btns[2][3].cget("text") == char)) or  
    ((btns[3][1].cget("text") == char) and (btns[3][2].cget("text") == char) and (btns[3][3].cget("text") == char)) or  
        #vertical
    ((btns[1][1].cget("text") == char) and (btns[2][1].cget("text") == char) and (btns[3][1].cget("text") == char)) or
    ((btns[1][2].cget("text") == char) and (btns[2][2].cget("text") == char) and (btns[3][2].cget("text") == char)) or
    ((btns[1][3].cget("text") == char) and (btns[2][3].cget("text") == char) and (btns[3][3].cget("text") == char)) or
        #diagonal
    ((btns[1][1].cget("text") == char) and (btns[2][2].cget("text") == char) and (btns[3][3].cget("text") == char)) or
    ((btns[1][3].cget("text") == char) and (btns[2][2].cget("text") == char) and (btns[3][1].cget("text") == char))):
        topMessage(char)


def main():
    global btns
    root = Tk()
    root.title("X and O of Daniar")
    root.resizable(False, False)
    btns = [None]
    for y in range(1, 4):
        row = [None]
        for x in range(1, 4):
            row.append(Button(root,
                              width=5,
                              height=3,
                              font="time 12 bold",
                              command=lambda x=x, y=y: clicked(y, x)))
            row[x].grid(row=y, column=x)
        btns.append(row)

    Button(root,
           text="Restart",
           width=5,
           command=lambda: restart(root)).grid(row=4, column=2)

    root.mainloop()

main()

另外,如果你对isWinner函数有什么更明智的建议,你能和我分享一下吗?你知道吗


Tags: orandtextinpyrootusersturn
1条回答
网友
1楼 · 发布于 2024-10-01 22:41:45

这会解决你的问题。你知道吗

您需要在函数外部定义一个变量才能将其与全局变量一起使用,并让main()使用该变量。另外,如果在命令中调用任何函数并将变量传递给该函数,请始终使用lambda。你知道吗

from tkinter import *

turn = True
btns = None
root = None


def clicked(y, x):
    global turn, btns
    char = ""
    if turn:
        char = "X"
    else:
        char = "O"

    btns[y][x].config(text=char,
                      state=DISABLED)
    isWinner(char)
    turn = not turn


def restart(root):
    global turn
    turn = True
    root.destroy()
    main()


def topMessage(char):
    global root
    top = Toplevel()
    top.title("Congratulations!")
    topText = Label(top, text=f"{char} is a winner!")
    topButton = Button(top, text="Restart", command=lambda: restart(root))
    topText.grid(row=0)
    topButton.grid(row=1)


def isWinner(char):
    global root
    # horizontal
    if (((btns[1][1].cget("text") == char) and (btns[1][2].cget("text") == char) and (btns[1][3].cget("text") == char)) or
        ((btns[2][1].cget("text") == char) and (btns[2][2].cget("text") == char) and (btns[2][3].cget("text") == char)) or
        ((btns[3][1].cget("text") == char) and (btns[3][2].cget("text") == char) and (btns[3][3].cget("text") == char)) or
        # vertical
        ((btns[1][1].cget("text") == char) and (btns[2][1].cget("text") == char) and (btns[3][1].cget("text") == char)) or
        ((btns[1][2].cget("text") == char) and (btns[2][2].cget("text") == char) and (btns[3][2].cget("text") == char)) or
        ((btns[1][3].cget("text") == char) and (btns[2][3].cget("text") == char) and (btns[3][3].cget("text") == char)) or
        # diagonal
        ((btns[1][1].cget("text") == char) and (btns[2][2].cget("text") == char) and (btns[3][3].cget("text") == char)) or
            ((btns[1][3].cget("text") == char) and (btns[2][2].cget("text") == char) and (btns[3][1].cget("text") == char))):
        topMessage(char)


def main():
    global btns
    global root
    root = Tk()
    root.title("X and O of Daniar")
    root.resizable(False, False)
    btns = [None]
    for y in range(1, 4):
        row = [None]
        for x in range(1, 4):
            row.append(Button(root,
                              width=5,
                              height=3,
                              font="time 12 bold",
                              command=lambda x=x, y=y: clicked(y, x)))
            row[x].grid(row=y, column=x)
        btns.append(row)

    Button(root,
           text="Restart",
           width=5,
           command=lambda: restart(root)).grid(row=4, column=2)

    root.mainloop()


main()

相关问题 更多 >

    热门问题