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

如何在Tkinter中高效绘制大量矩形(耗时≤3秒)

优化Tkinter大量矩形绘制的解决方案

你当前代码要绘制350000个独立矩形,每次调用canvas.create_rectangle都会触发一次GUI渲染指令,频繁的API调用是速度慢的核心原因——35万次交互的开销极大。以下是几种能把绘制时间控制在3秒以内的优化方案:

方案一:用网格线替代独立矩形(最快,耗时<0.1秒)

因为你的矩形是规则排列的网格,不需要逐个绘制,只需画所有水平和垂直线条,视觉效果和原代码完全一致,但绘制量骤减:

from tkinter import *

root = Tk()
canvas = Canvas(width=500, height=500)
canvas.grid(row=0, column=0)

Vscroll = Scrollbar(orient="vertical", command=canvas.yview)
Hscroll = Scrollbar(orient="horizontal", command=canvas.xview)

col_count = 50
col_width = 135
row_count = 7000
row_height = 30

# 绘制垂直线(50列需要51条线)
for col in range(col_count + 1):
    x = col * col_width
    canvas.create_line(x, 0, x, row_count * row_height, width=1, fill="grey60")

# 绘制水平线(7000行需要7001条线)
for row in range(row_count + 1):
    y = row * row_height
    canvas.create_line(0, y, col_count * col_width, y, width=1, fill="grey60")

# 填充白色背景,和原代码效果一致
canvas.create_rectangle(0, 0, col_count * col_width, row_count * row_height, fill="white")

canvas.update_idletasks()
canvas.config(scrollregion=canvas.bbox("all"), xscrollcommand=Hscroll.set, yscrollcommand=Vscroll.set)
Hscroll.grid(row=1, column=0, sticky='ew')
Vscroll.grid(row=0, column=1, sticky='ns')

if __name__ == "__main__":   
    mainloop()

方案二:用PhotoImage批量绘制(适合需自定义单格样式)

如果需要给部分矩形设置不同填充色/样式,可在内存中的PhotoImage里批量绘制,再一次性贴到Canvas:

from tkinter import *

root = Tk()
canvas = Canvas(width=500, height=500)
canvas.grid(row=0, column=0)

Vscroll = Scrollbar(orient="vertical", command=canvas.yview)
Hscroll = Scrollbar(orient="horizontal", command=canvas.xview)

col_count = 50
col_width = 135
row_count = 7000
row_height = 30

# 创建对应尺寸的PhotoImage
img = PhotoImage(width=col_count * col_width, height=row_count * row_height)

# 批量绘制矩形(只画右侧和下侧边框避免重复)
for col in range(col_count):
    x1 = col * col_width
    x2 = x1 + col_width
    for row in range(row_count):
        y1 = row * row_height
        y2 = y1 + row_height
        # 填充白色背景
        img.put("white", to=(x1, y1, x2, y2))
        # 绘制右侧边框
        img.put("grey60", to=(x2-1, y1, x2-1, y2))
        # 绘制下侧边框
        img.put("grey60", to=(x1, y2-1, x2, y2-1))

# 补全顶部和左侧的边框
img.put("grey60", to=(0, 0, col_count*col_width-1, 0))
img.put("grey60", to=(0, 0, 0, row_count*row_height-1))

# 将图像贴到Canvas
canvas.create_image(0, 0, image=img, anchor=NW)

canvas.update_idletasks()
canvas.config(scrollregion=canvas.bbox("all"), xscrollcommand=Hscroll.set, yscrollcommand=Vscroll.set)
Hscroll.grid(row=1, column=0, sticky='ew')
Vscroll.grid(row=0, column=1, sticky='ns')

if __name__ == "__main__":   
    mainloop()

方案三:用PIL库加速绘制(适合复杂图形)

如果PhotoImage功能不够,可用PIL的ImageDraw高效绘制,再转成Tkinter兼容的图像(需先执行pip install pillow安装PIL):

from tkinter import *
from PIL import Image, ImageDraw, ImageTk

root = Tk()
canvas = Canvas(width=500, height=500)
canvas.grid(row=0, column=0)

Vscroll = Scrollbar(orient="vertical", command=canvas.yview)
Hscroll = Scrollbar(orient="horizontal", command=canvas.xview)

col_count = 50
col_width = 135
row_count = 7000
row_height = 30

# 创建PIL图像并初始化绘制对象
img = Image.new("RGB", (col_count * col_width, row_count * row_height), "white")
draw = ImageDraw.Draw(img)

# 批量绘制网格线
for col in range(col_count + 1):
    x = col * col_width
    draw.line([(x, 0), (x, row_count * row_height)], fill="#999999", width=1)

for row in range(row_count + 1):
    y = row * row_height
    draw.line([(0, y), (col_count * col_width, y)], fill="#999999", width=1)

# 转成Tkinter可用的图像
tk_img = ImageTk.PhotoImage(img)

# 贴到Canvas
canvas.create_image(0, 0, image=tk_img, anchor=NW)

canvas.update_idletasks()
canvas.config(scrollregion=canvas.bbox("all"), xscrollcommand=Hscroll.set, yscrollcommand=Vscroll.set)
Hscroll.grid(row=1, column=0, sticky='ew')
Vscroll.grid(row=0, column=1, sticky='ns')

if __name__ == "__main__":   
    mainloop()

内容的提问来源于stack exchange,提问作者Apata John

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 13:01:43