4
我正在使用Tkinter编写康威的生活游戏,我想要一个允许动画开始的“开始”按钮,并自动继续步进直到终止。我使用Canvas绘制环境,但由于“Go”按钮需要在更新画布之前完成函数调用,因此窗口会挂起,直到我终止进程。我试图用canvas.update_idletasks()
和canvas.update()
(接着睡几秒钟)在我想更新画布的点上,但这似乎并没有成功。有任何想法吗?以下是我的GameOfLife类,Environment类仅管理单元的“板”。如何在函数调用过程中更新Tkinter画布?
from Tkinter import *
from random import *
from time import time
from Environment import *
class GameOfLife(object):
def __init__(self, master, envDim):
self.unitSize = 10
self.dimension = envDim * self.unitSize
self.environment = Environment(envDim)
self.environment.seedBoard()
self.started = False
frame = Frame(master)
frame.pack()
Button(frame, text = "Go", command = self.go_call).pack(side = LEFT)
Button(frame, text = "Clear", command = self.reset_call).pack(side = LEFT)
Button(frame, text = "Close", command = frame.quit).pack(side = RIGHT)
canvas = self.drawCanvas(master, self.dimension)
def drawCanvas(self, master, dimension):
self.canvas = Canvas(master, width = self.dimension, height = self.dimension)
self.canvas.pack()
return self.canvas
def go_call(self):
print "<< Go Call >>"
if self.environment.started == False:
self.environment.seedBoard()
self.drawState(self.environment)
self.environment.nextBoard()
self.started = True
while True:
self.environment.nextBoard()
self.canvas.delete(ALL)
self.drawState(self.environment)
self.canvas.update_idletasks()
sleep(4)
def reset_call(self):
print "<< Reset Call >>"
self.canvas.delete(ALL)
self.environment = Environment(self.environment.dim)
def drawState(self, environment):
size = self.unitSize
for x in range(environment.dim):
for y in range(environment.dim):
if environment.matrix[x][y].alive == True:
xs = x * size
ys = y * size
self.canvas.create_rectangle(xs, ys, xs+size, ys+size, fill = 'black')
envDim = 70
root = Tk()
gol = GameOfLife(root, envDim)
root.mainloop()
小建议。看起来您要删除所有画布对象,并在每次状态更新时创建新对象。将相同的矩形保留在画布上并在每次迭代中更改其填充颜色可能会更有效。 –
为什么“睡觉”4秒钟,是不是很多? – Amr
与问题无关,但在示例代码中执行像您这样的导入确实是一个糟糕的主意 - 除非您确切知道每个模块导出的内容可能很容易产生名称冲突。作为一个经验法则,你不应该'输入*'。 –