编写以下代码以在Python中使用Tkinter显示棋盘:
import tkinter as tk
class Gui(tk.Tk):
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super().__new__(cls, *args, **kwargs)
cls._instance.__initialized = False
return cls._instance
def __init__(self):
if self.__initialized:
return
self.__initialized = True
super().__init__()
class Color(object):
white =(0xff,0xff,0xff)
black =(0x00,0x00,0x00)
class Tile(tk.PhotoImage):
@staticmethod
def putTile(image, color, width, height, coordinates):
pix = "#%02x%02x%02x" % color
coor = (coordinates[0]*width, coordinates[1]*height)
line = "{" + " ".join([pix]*width) + "}"
image.put(" ".join([line]*height),coor)
class Grid(tk.PhotoImage):
def __init__(self,grid):
super().__init__(width=10*len(grid), height=10*len(grid[0]))
for x in range(len(grid)):
for y in range(len(grid[x])):
Tile.putTile(self,Color.white if grid[x][y]==1 else
Color.black,10,10,(x,y))
class ChessBoard(Grid):
chessboard = 4 * ([4 * [0,1]] + [4 * [1,0]])
def __init__(self):
super().__init__(self.chessboard)
所以Gui()
实现为单例模式。另外tk.Tk.__init__()
只被调用一次,另外我每次调用Gui()
时都会看到一个窗口。
我希望以下内容显示一个带棋盘的窗口:
案例1:
label = tk.Label(Gui(), image=ChessBoard())
label.pack()
Gui().mainloop()
这会创建一个没有错误或警告的空窗口。 print语句显示确实调用了方法tilePut
。
只有当我在程序中添加额外的Gui()
语句时,如下所示,每个语句都完美无缺,并且会打印棋盘。
案例2:
Gui()
label = tk.Label(Gui(), image=ChessBoard())
label.pack()
Gui().mainloop()
所以我想image.put
来电需要Gui()
才能存在。虽然如果我尝试以下代码:
案例3:
board = ChessBoard()
label = tk.Label(Gui(), image=board)
label.pack()
Gui().mainloop()
我很快就会调用image.put
。考虑到我在案例1中没有得到同样的错误,我很惊讶案例1不起作用。任何人都可以解释原因吗?
答案 0 :(得分:2)
您的问题的答案可归结为两个因素:
使用此代码的正确方法是首先创建Gui
的实例,然后创建Chessboard
并保存变量中返回的内容。然后,您可以在其余代码中使用这些引用。
这是实现这一目标的常用方法:
root = Gui()
chessboard = ChessBoard()
label = tk.Label(root, image=chessboard)
label.pack()
root.mainloop()
由于您将Gui
定义为单身,因此以下内容也适用。但是,我认为使用单例会增加复杂性并使代码不那么清晰,因为看起来您正在创建三个Gui
实例:
Gui()
chessboard = ChessBoard()
label = tk.Label(Gui(), image=chessboard)
label.pack()
Gui().mainloop()