使用tkinter可视化星形搜索算法

时间:2015-08-30 13:06:44

标签: python tkinter a-star

我已经编写了一个A *搜索算法,想要使用tkinter以图形方式显示搜索(实时),如下图所示,只是一个没有菜单的简单版本,单元格中的数字,以前尝试过的路径或对角线路径

换句话说,我只需要显示一个网格,其中包含7种可能的纹理(开始,结束,路径,障碍,开放节点,闭合节点,未尝试),当基础矩阵发生变化时,它会自动更新。

可以这么说,或者这种外观的架构如何?我已经有一个2x2矩阵,包含每个节点状态的值(开始..障碍等等),我怎样才能使用tkinter每次更改时显示这个矩阵?

a

到目前为止,我得到了这个:

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窗口。怎么了?

1 个答案:

答案 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]