You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何刷新Canvas以显示Python康威生命游戏中动态变化的矩阵网格

解决Tkinter中康威生命游戏Canvas逐代更新的问题

你的核心问题在于两点:一是当前drawgrid每次都会创建新的Canvas控件,没有复用已有的Canvas进行更新;二是缺少触发逐代演化并刷新界面的循环逻辑。下面是修改后的完整解决方案:

修改后的代码

import numpy as np
from tkinter import *

def makegrid(rows, cols):
    grid = np.zeros((rows, cols), int)
    return grid

def insertpattern(x, y, pattern, grid):
    for i in range(pattern.shape[0]):
        for j in range(pattern.shape[1]):
            grid[x + i][y + j] = pattern[i][j]
    return grid

def enviroment(x, y, grid):
    sum = 0
    for i in range(3):
        for j in range(3):
            if i == 1 and j == 1:
                continue
            elif (x - 1 + i < 0) or (y - 1 + j < 0) or (x - 1 + i == grid.shape[0]) or (y - 1 + j == grid.shape[1]):
                continue
            else:
                sum += grid[x - 1 + i][y - 1 + j]
    return sum

def nextgen(grid):
    grid2 = makegrid(grid.shape[0], grid.shape[1])
    for i in range(grid.shape[0]):
        for j in range(grid.shape[1]):
            if grid[i][j] == 1:
                if enviroment(i, j, grid) == 2 or enviroment(i, j, grid) == 3:
                    grid2[i][j] = 1
            elif grid[i][j] == 0:
                if enviroment(i, j, grid) == 3:
                    grid2[i][j] = 1
            else:
                grid2[i][j] = 0
    return grid2

# 修改drawgrid:复用已有Canvas,先清空再重绘
def drawgrid(grid, display, cell_size):
    # 清空Canvas上所有元素
    display.delete("all")
    for i in range(grid.shape[0]):
        for j in range(grid.shape[1]):
            fill = "black"
            outline = "grey"
            if grid[i][j] == 1:
                fill = "green"
                outline = "grey"
            xmin = j * cell_size
            xmax = xmin + cell_size
            ymin = i * cell_size
            ymax = ymin + cell_size
            display.create_rectangle(xmin, ymin, xmax, ymax, fill=fill, outline=outline)

# 新增更新函数,用after实现定时循环
def update_game():
    global grid
    # 生成下一代网格
    grid = nextgen(grid)
    # 更新Canvas显示
    drawgrid(grid, display, CELL_SIZE)
    # 每隔300ms调用一次自己,控制演化速度
    app.after(300, update_game)

ROWS = 20
COLS = 20
CELL_SIZE = 30
grid = makegrid(ROWS, COLS)
pattern = np.ones((3, 1), int)
grid = insertpattern(1, 1, pattern, grid)

app = Tk()
app.title("Game of life")
# 先创建Canvas并打包
display = Canvas(app, width=CELL_SIZE * COLS, height=CELL_SIZE * ROWS)
display.pack()
# 首次绘制初始网格
drawgrid(grid, display, CELL_SIZE)
# 启动演化更新循环
update_game()

app.mainloop()

关键修改说明

  • 复用Canvas更新:把原来返回新Canvas的drawgrid改成接受已创建的display参数,先通过display.delete("all")清空旧内容,再重新绘制新网格。
  • 定时循环触发:新增update_game函数,它会生成下一代网格、调用drawgrid刷新界面,然后用app.after(300, update_game)设定300毫秒后再次调用自己,实现无阻塞的逐代演化(可以调整300这个数值来改变速度)。
  • 全局变量传递:用global grid让update_game能修改全局的网格变量,确保每一代的演化是连续的。

内容的提问来源于stack exchange,提问作者Maher Abdellatif

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 14:25:43