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

tkinter中canvas.create_image返回值能否存入列表?该如何正确操作?

问题解答

1. create_image返回值相关说明

canvas.create_image()的返回值就是对应画布元素的整数ID,类型为int属于正常情况,完全可以存入列表,你打印得到的[1, 2]就是创建的两个图片元素的合法ID,后续可以通过这些ID对画布上的图片进行移动、修改属性、删除等操作,存ID的操作本身没有错误。

2. 前期图片消失的原因

图片消失和存ID的操作无关,是Tkinter的PhotoImage对象垃圾回收机制导致的:Tkinter底层不会持有ImageTk.PhotoImage实例的引用计数,当Python侧没有任何存活变量引用该实例时,实例就会被垃圾回收,画布上对应的图片就无法渲染显示。
你当前代码中第一个photoImg在第二张图片创建完成后没有被其他变量持有,因此被回收,第一张图随之消失;第二个photoImg2仍有变量引用,所以可以正常显示。

3. 正确实现方式

你需要额外维护一个列表,专门存储所有ImageTk.PhotoImage实例,保证图片显示期间实例不会被回收,参考修改后的代码:

from PIL import Image
from PIL import ImageTk
import tkinter as tk

# 初始化根窗口
root = tk.Tk()
# 分别存储画布元素ID、PhotoImage实例
canvas_image_ids = []
canvas_photo_images = []
canvas = tk.Canvas(root, width=640, height=640)
canvas.pack()

# 第一张图
img = Image.open(imgDirectory)
img = img.resize((170, 170), Image.ANTIALIAS)
photo_img = ImageTk.PhotoImage(img)
canvas_image_ids.append(canvas.create_image(100, 100, image=photo_img))
canvas_photo_images.append(photo_img) # 保留实例引用,避免被回收

# 第二张图
img2 = Image.open(imgDirectory2)
img2 = img2.resize((170, 170), Image.ANTIALIAS)
photo_img2 = ImageTk.PhotoImage(img2)
# 坐标调整为300,100避免两张图重叠
canvas_image_ids.append(canvas.create_image(300, 100, image=photo_img2))
canvas_photo_images.append(photo_img2) # 保留实例引用

print(canvas_image_ids)
print(type(canvas_image_ids[0]))

root.mainloop()

如果不需要单独维护ID,也可以将ID和PhotoImage实例以元组形式存入同一个列表,只要保证PhotoImage实例在图片显示周期内始终被引用即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 00:45:03