所以,我正在使用tkinter为Tic Tac Toe写一个gui,而我正试图实现一个" Undo"特征
我有一个班级" Square"它是canvas的子类,具有绘制零,交叉或清除自身的方法。 "撤消"函数应该计算出最近播放的正方形,并在其上调用clear方法。
我有一个所有动作的全局列表,名为" notation",所以如果我能够在notation.pop()返回的对象上调用clear函数,这应该可以。
这是实现这个的合理方式,我该怎么做?
以下是我的代码,以及我当前的"撤消"按钮,硬编码只能撤消C,即中心广场。
import tkinter as tk
# notation is a list containing all moves made
notation = []
# This class defines a Square, just a clickable canvas which shows a nought or cross when clicked
class Square(tk.Canvas):
def __init__(self, name, master=None, width=None, height=None):
super().__init__(master, width=width, height=height)
self.bind("<Button-1>", self.tic)
self.bind("<Button-2>", self.tac)
self.free=True
self.name=name
def tic(self, event):
""""This will draw a cross on the selected Square."""
if self.free:
self.create_line(30, 30, 170, 170)
self.create_line(30, 170, 170, 30)
self.free = False
global notation
notation.append(self.name)
print(notation)
def tac(self, event):
""""This will draw a nought on the selected Square."""
if self.free:
self.create_oval(30, 30, 170, 170)
self.free = False
global notation
notation.append(self.name)
print(notation)
def clear(self):
""""This will clear the selected Square."""
if not self.free:
self.delete("all")
self.free = True
global notation
notation.pop()
print(notation)
root = tk.Tk()
root.title("Tic Tac Toe")
NW = Square("NW", master=root, width=200, height=200)
NW.grid(row=0, column=0)
N = Square("N", master=root, width=200, height=200)
N.grid(row=0, column=1)
NE = Square("NE", master=root, width=200, height=200)
NE.grid(row=0, column=2)
W = Square("W", master=root, width=200, height=200)
W.grid(row=1, column=0)
C = Square("C", master=root, width=200, height=200)
C.grid(row=1, column=1)
E = Square("E", master=root, width=200, height=200)
E.grid(row=1, column=2)
SW = Square("SW", master=root, width=200, height=200)
SW.grid(row=2, column=0)
S = Square("S", master=root, width=200, height=200)
S.grid(row=2, column=1)
SE = Square("SE", master=root, width=200, height=200)
SE.grid(row=2, column=2)
# Creating File Menu
menu = tk.Menu(root)
root.config(menu=menu)
fileMenu = tk.Menu(menu)
menu.add_cascade(label="File", menu=fileMenu)
fileMenu.add_command(label="Undo", command=lambda: C.clear())
root.mainloop()
答案 0 :(得分:1)
你有一个正确的想法。您需要做的是将整个实例添加到符号列表中,然后当您弹出最后一个实例时,您可以将其称为明确的方法:
def tac(self, event):
notation.append(self) # add this instance to the list
...
fileMenu.add_command(label="Undo", command=lambda: notation.pop().clear())
在清除方法中摆脱pop
。
编辑:您可能知道,全局变量很糟糕。在这种情况下,我们使用类变量,它们基本上是可由类的所有实例访问的实例变量。类变量是在方法之外定义的,没有&#34; self。&#34;前缀,但是你需要使用类名或&#34; self&#34;访问它(例如,在您的情况下,您可以从课程内部使用self.notaion
或从外部Square.notation
访问它)。我们还将使用类方法来操作它们。看看你是否能理解这一点:
import tkinter as tk
class Square(tk.Canvas):
notation = [] # this is a class variable
def __init__(self, name, master=None, width=None, height=None):
super().__init__(master, width=width, height=height)
self.bind("<Button-1>", self.tic)
self.bind("<Button-2>", self.tac)
self.free=True
self.name=name
def tic(self, event):
""""This will draw a cross on the selected Square."""
if self.free:
self.create_line(30, 30, 170, 170)
self.create_line(30, 170, 170, 30)
self.free = False
self.notation.append(self)
self.print()
def tac(self, event):
""""This will draw a nought on the selected Square."""
if self.free:
self.create_oval(30, 30, 170, 170)
self.free = False
self.notation.append(self)
self.print()
def clear(self):
""""This will clear the selected Square."""
if not self.free:
self.delete("all")
self.free = True
self.print()
@classmethod
def undo(cls):
cls.notation.pop().clear()
@classmethod
def print(cls):
print('History:', *[s.name for s in cls.notation])
root = tk.Tk()
root.title("Tic Tac Toe")
for i, name in enumerate('NW N NE W C E SW S SE'.split()):
s = Square(name, master=root, width=200, height=200)
row, column = divmod(i, 3)
s.grid(row=row, column=column)
# Creating File Menu
menu = tk.Menu(root)
root.config(menu=menu)
fileMenu = tk.Menu(menu)
menu.add_cascade(label="File", menu=fileMenu)
fileMenu.add_command(label="Undo", command=Square.undo)
root.mainloop()
我也摆脱了你的重复。记住干......如果你是复制/粘贴代码,那么你正在做计算机的工作。