我已经编写了一个A *搜索算法,想要使用tkinter以图形方式显示搜索(实时),如下图所示,只是一个没有菜单的简单版本,单元格中的数字,以前尝试过的路径或对角线路径
换句话说,我只需要显示一个网格,其中包含7种可能的纹理(开始,结束,路径,障碍,开放节点,闭合节点,未尝试),当基础矩阵发生变化时,它会自动更新。
可以这么说,或者这种外观的架构如何?我已经有一个2x2矩阵,包含每个节点状态的值(开始..障碍等等),我怎样才能使用tkinter每次更改时显示这个矩阵?
到目前为止,我得到了这个:
def main():
theMap = .. # initial map with start, finish and obstacles
root = Tk()
my_gui = CellGrid(root,n,m,40,theMap)
root.mainloop()
class CellGrid(Canvas):
def __init__(self,master, rowNumber, columnNumber, cellSize, theMap):
Canvas.__init__(self, master, width = cellSize * columnNumber , height = cellSize * rowNumber)
self.cellSize = cellSize
self.grid = []
for row in range(rowNumber):
line = []
for column in range(columnNumber):
line.append(Cell(self, column, row, cellSize, theMap[row][column]))
self.grid.append(line)
print self.grid[0][0].value
self.draw()
def draw(self):
for row in self.grid:
for cell in row:
cell.draw()
class Cell():
START_COLOR = "green"
FINISH_COLOR = "red"
UNTRIED_COLOR = "white"
CLOSED_COLOR = "gray"
OPEN_COLOR = "blue"
OBSTACLE_COLOR = "black"
PATH_COLOR = "orange"
def __init__(self, master, x, y, size, value):
self.master = master
self.abs = x
self.ord = y
self.size= size
self.fill = "white"
self.value = value
def setValue(self, value):
self.value = value
def draw(self):
""" order to the cell to draw its representation on the canvas """
if self.master != None :
if self.value == 0:
self.fill = self.UNTRIED_COLOR
elif self.value == 1:
self.fill = self.OBSTACLE_COLOR
elif self.value == 2:
self.fill = self.START_COLOR
elif self.value == 3:
self.fill = self.FINISH_COLOR
elif self.value == 4:
self.fill = self.OPEN_COLOR
elif self.value == 5:
self.fill = self.CLOSED_COLOR
elif self.value == 6:
self.fill = self.PATH_COLOR
xmin = self.abs * self.size
xmax = xmin + self.size
ymin = self.ord * self.size
ymax = ymin + self.size
self.master.create_rectangle(xmin, ymin, xmax, ymax, fill = self.fill, outline = "black")
想法是绘制仅包含开始,结束和障碍节点的初始地图(theMap)。然后,当A *更改节点时,它可以使用节点的新值调用CellGrid中的方法,然后更新该值并绘制相应的纹理。
然而,我无法做到那么远。当我运行上面的代码时,我什么都没得到,只是一个空的Tk窗口。怎么了?
答案 0 :(得分:2)
发布的代码未运行。它(以3.x开头),例如,用
开始from tkinter import *
def main():
Map = [
[2, 0, 0, 0, 0],
[0, 1, 1, 1, 1],
[0, 1, 3, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 0, 0, 0],
]
root = Tk()
my_gui = CellGrid(root, len(Map), len(Map[0]), 40, Map)
root.mainloop()
并将括号添加到print语句中。
print(self.grid[0][0].value) # harmless in 2.7
以main()
结尾。使用简单数据对开发非常有帮助。
要回答您的直接问题,要使画布可见,需要在Canvas初始化后添加self.pack
。这样,上面的地图就会按预期显示。
要回答您的架构问题,我建议采用不同的方法。定义一个自定义Map类,其中包含您当前称为Map的列表列表,Canvas,以及带有索引元组的 getitem 和 setitem 方法。用amap [(i,j)]写出你的A *函数。 setitem 方法将负责设置数组和画布。
Python样式注意:上面的所有颜色代码都可以替换为
colors = {
0: 'white', # untried
1: 'black', # obstacle
2: 'green', # start
3: 'red', # finish
4: 'blue', # open
5: 'gray', # closed
6: 'orange', # path
}
在create_rectangle调用中跟随fill=colors[self.value]
。