在Tkin函数中改变变量

2024-06-26 01:34:48 发布

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

我想X和O动画切换来回鼠标点击。问题出在函数XorO中。我真的不明白为什么,但它只会创建Xs当我点击它。我想这可能与我如何编写turn变量有关。这是我的东西

from tkinter import *


tk = Tk()
width = 600
third = width / 3
canvas = Canvas(width=width, height=width)
tk.title = ("Tic Tac Toe")


line1 = canvas.create_line(200, 0, 200, 600)
line2 = canvas.create_line(400, 0, 400, 600)
line3 = canvas.create_line(0, 200, 600, 200)
line4 = canvas.create_line(0, 400, 600, 400)



def mouse_click(event):
    col = int(event.x / third)
    row = int(event.y / third)
    XorO(row, col)

def XorO(row,col):
    class XsorOs:
        turn = 1
        if turn is (1 or 3 or 5 or 7 or 9):
            canvas.create_line(col * third, row * third, (col + 1) * third, (row + 1) * third)
            canvas.create_line((col + 1) * third, row * third, col * third, (row + 1) * third)

        else:
            canvas.create_oval(col * third + 5, row * third + 5, (col + 1) * third - 5, (row + 1) * third - 5)
        turn += 1

canvas.pack()
canvas.bind("<Button-1>", mouse_click)
canvas.mainloop()

Tags: oreventdefcreatelinecolwidthtk
2条回答

我从你的代码中做了一些调整,成功地修复了它。但是,我可以让它,如果一个X被创建,一个O和X不能在同一个磁贴上创建吗?谢谢你的帮助。这就是我目前所拥有的

from tkinter import *


tk = Tk()
width = 600
third = width / 3
canvas = Canvas(width=width, height=width)
tk.title = "Tic Tac Toe"


line1 = canvas.create_line(200, 0, 200, 600)
line2 = canvas.create_line(400, 0, 400, 600)
line3 = canvas.create_line(0, 200, 600, 200)
line4 = canvas.create_line(0, 400, 600, 400)


class XsorOs:
    def __init__(self):
        self.turn = 0
        self.clicked = []

    def click(self, row, col):
        if (row, col) not in self.clicked
            if self.turn is 0:
                canvas.create_line(col * third, row * third, (col + 1) * third, (row + 1) * third)
                canvas.create_line((col + 1) * third, row * third, col * third, (row + 1) * third)
                self.turn += 1
            elif self.turn is 1:
                canvas.create_oval(col * third + 5, row * third + 5, (col + 1) * third - 5, (row + 1) * third - 5)
                self.turn -= 1
            else:
                print("Game Over")
            self.clicked.append((row, col))


def mouse_click(c, event):
    col = int(event.x / third)
    row = int(event.y / third)
    c.click(row, col)


xo = XsorOs()
canvas.pack()
canvas.bind("<Button-1>", lambda event: mouse_click(xo, event))
canvas.mainloop()

另外,如果你有理由使用我在评论中提到的方法,如果你能解释一下原因,我将不胜感激

这里的问题是每次调用XsorOs方法时都会创建XorO对象。这意味着XsorOs.turn总是1。 一种方法是从外部跟踪turn,并用global调用它,但是 当然global是一个应该避免的东西,尤其是它可能会变得非常混乱。 我建议在Tk单独的“logic”类的一个子类中跟踪turn

我给你举了一个例子:

(请注意,这个例子非常草率(特别是变量命名),应该只是告诉你我的意思)

# stays the same until 'line4 = canvas.create_line(0, 400, 600, 400)'
class XsorOs:
    def __init__(self):
        self.turn = 1

    def click(self, row, col):
        if self.turn is (1 or 3 or 5 or 7 or 9):
            canvas.create_line(col * third, row * third, (col + 1) * third, (row + 1) * third)
            canvas.create_line((col + 1) * third, row * third, col * third, (row + 1) * third)
        else:
            canvas.create_oval(col * third + 5, row * third + 5, (col + 1) * third - 5, (row + 1) * third - 5)
            self.turn += 1


def mouse_click(c, event):
    col = int(event.x / third)
    row = int(event.y / third)
    c.click(row, col)


xo = XsorOs()
canvas.pack()
canvas.bind("<Button-1>", lambda event: mouse_click(xo, event))
canvas.mainloop()

编辑:

  • lambda基本上是一种创建单行函数的方法。在本例中,我使用它通过事件函数传递参数。因为在内部某处tkinter做了类似于if that mouseclick happens do passed_function(event)的事情,所以你没有机会使用你自己的论点。这就是lambda在这里有用的原因

  • __init__在这里可能没有那么重要,因为我以前看到人们在类主体中放置变量,显然它工作得很好,但我个人更喜欢它在构造函数中创建类的所有变量

  • self在其他语言中类似于this对类或该类的对象的引用(实际上可以通过命名第一个构造函数参数来命名它,但是self是常用的)。它“拉”类范围内的变量,而不是函数。这意味着变量存在并且只要对象存在就可以被操纵。函数在执行后基本上会丢失所有内容。这是您以前的代码中的主要问题

相关问题 更多 >