关于python:为什么要显示我的tkinter画布?

Why is my Tkinter canvas displaying?

我正在尝试使用tkinter二维图形用户界面生成一个星型算法。我修改了以下代码,在这里找到了它:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
from tkinter import *

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():
    colors = {
            0: 'white',    # untried
            1: 'black',    # obstacle
            2: 'green',    # start
            3: 'red',      # finish
            4: 'blue',     # open
            5: 'gray',     # closed
            6: 'orange',   # path
         }

    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):
         if self.master != None :
            if self.value == 0:
                self.fill = self.white
            elif self.value == 1:
                self.fill = self.black
            elif self.value == 2:
                self.fill = self.green
            elif self.value == 3:
                self.fill = self.red
            elif self.value == 4:
                self.fill = self.blue
            elif self.value == 5:
                self.fill = self.gray
            elif self.value == 6:
                self.fill = self.orange

            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")

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()
    c = tk.Canvas(root, height=1000, width=1000, bg='white')
    my_gui = CellGrid(root, len(Map), len(Map[0]), 40, Map)


    root.mainloop()

但当我运行它时,没有显示任何内容。


很多小而非小的误解阻碍了星型算法的显示。

问题1-调用main()函数不完整。

As @avysk suggests as comment, the first blocking point is due to the
missing of main() preamble in Python.

只需在def main()函数后添加以下代码:

1
2
if __name__ == '__main__':
    main()

问题2-主Canvas显示器的打字错误和缺少pack()

由于未定义tk符号,主画布声明如下:

1
c = Canvas(root, height=1000, width=1000, bg='white')

而不是:

1
c = tk.Canvas(root, height=1000, width=1000, bg='white')

在神奇的失踪电话是pack()之后:

1
c.pack() # magic call to display the (1000 x 1000) white canvas

问题3-辅助Canvas显示器的呼叫丢失。

对于主Canvas,缺少pack()的调用,可以使用两种可能性来显示辅助Canvas

  • 增加my_gui.pack()以使主Canvas与次Canvas的大小相适应,
  • 或者我的首选解决方案,添加my_gui.place(relx=0.5, rely=0.5, anchor=CENTER),使辅助Canvas居中到主Canvas
  • 要显示辅助Canvas

    1
    2
    my_gui = CellGrid(c, len(Map), len(Map[0]), 40, Map)
    my_gui.place(relx=0.5, rely=0.5, anchor=CENTER)

    问题4——对Cell::draw()函数中字典使用的误解。

    The displayed error is"AttributeError: 'Cell' object has no attribute 'green'".

    第一个单元格的值self.grid[0][0].value = 2和绘制单元格时,后面的self.fill = self.green生成错误。

    有三种方法可以用来解决这个错误:

  • self.fill = ''代替self.fill = self.7例,
  • 使用已声明的字典colors,用一个唯一的调用替换7个案例。
  • 字典的使用可以是(sol 2):

    1
    2
    if 0 <= self.value <= 6: # check if value in range of colors
        self.fill = Cell.colors[self.value]

    而不是长if elif(sol 1):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
        if self.value == 0:
            self.fill = 'white' # Error: self.white
        elif self.value == 1:
            self.fill = 'black' # Error: self.black
        elif self.value == 2:
            self.fill = 'green' # Error: self.green
        elif self.value == 3:
            self.fill = 'red' # Error: self.red
        elif self.value == 4:
            self.fill = 'blue' # Error: self.blue
        elif self.value == 5:
            self.fill = 'gray' # Error: self.gray
        elif self.value == 6:
            self.fill = 'orange' # Error: self.orange