为啥我的 Tkinter 画布显示?
Posted
技术标签:
【中文标题】为啥我的 Tkinter 画布显示?【英文标题】:Why is my Tkinter canvas displaying?为什么我的 Tkinter 画布显示? 【发布时间】:2017-07-15 18:24:58 【问题描述】:我正在尝试使用 Tkinter 2d 图形用户界面生成星型算法。我已经修改了以下代码,最初是在这里找到的:
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()
但是当我去运行它时,什么都没有显示。
【问题讨论】:
你确定你运行任何东西吗? Python 不是 C,名为main()
的函数并不特殊,不会自动运行。你应该明确地调用它。 (见这里:***.com/questions/22492162/…)
你的标题询问为什么画布正在显示。您是在问为什么它会显示,或者为什么它没有显示?如果是后者,你应该在标题中这样说。
【参考方案1】:
很多小不点的误会阻碍了star算法的展示。
问题 1 - 不完整的调用 main()
函数。
正如@avysk 建议的评论,第一个阻塞点是由于 Python 中缺少
main()
序言。
只需在def main()
函数后添加如下代码:
if __name__ == '__main__':
main()
问题 2 - 在主 Canvas
显示中出现拼写错误和缺少 pack()
。
由于tk
符号未定义,主Canvas应声明如下:
c = Canvas(root, height=1000, width=1000, bg='white')
代替:
c = tk.Canvas(root, height=1000, width=1000, bg='white')
在神奇的失踪电话之后是pack()
:
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
:
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()
函数中字典使用的误解。
显示的错误是“
AttributeError: 'Cell' object has no attribute 'green'
”。
第一个单元格self.grid[0][0].value = 2
的值和绘制单元格时,下面的self.fill = self.green
会产生错误。
可以使用三种可能性来解决该错误:
-
将
self.fill = self.<color>
(7 例)替换为self.fill = '<color>'
,
使用声明的字典 colors
并用唯一的调用替换这 7 个案例。
字典的使用可以是(sol 2):
if 0 <= self.value <= 6: # check if value in range of colors
self.fill = Cell.colors[self.value]
而不是冗长的 if-elif (sol 1):
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
【讨论】:
以上是关于为啥我的 Tkinter 画布显示?的主要内容,如果未能解决你的问题,请参考以下文章
Tkinter 画布图像适用于 Windows 但不适用于 OSX