在Tkinter Canvas上绘制矩形失败且无报错,求解决方案
问题描述
我尝试在Tkinter Canvas内的图片上绘制一个简单矩形,但矩形无法显示,且无任何报错。我未使用canvas.create_image方法,而是将图片放入Frame后嵌入Canvas,这是实现图片全图滚动的唯一方式,请问这是矩形无法绘制的原因吗?
问题原因
是的,这就是矩形无法显示的核心原因:
- Tkinter的Canvas组件中,通过
create_window添加的Widget(比如代码里的fTableFrame),层级会高于Canvas自身绘制的图形(比如用create_rectangle画的矩形)。 - Frame里的图片Label完全覆盖了Canvas的左上角区域,矩形被Frame和Label彻底挡住,因此无法显示。
解决方法
提供两种可行的解决思路:
思路一:直接在Canvas上加载图片(推荐)
放弃用Frame包裹图片的方式,直接用canvas.create_image把图片画在Canvas上,矩形可以直接画在图片上层,同时也能实现滚动:
import tkinter as tk from PIL import ImageTk, Image root = tk.Tk() canvas = tk.Canvas(root) hor_scroll_bar = tk.Scrollbar(root, orient=tk.HORIZONTAL, command=canvas.xview) ver_scroll_bar = tk.Scrollbar(root, orient=tk.VERTICAL, command=canvas.yview) canvas.config(xscrollcommand=hor_scroll_bar.set, yscrollcommand=ver_scroll_bar.set, highlightthickness=0) # 加载图片并绘制到Canvas img = ImageTk.PhotoImage(file="test.jpg") canvas.create_image(0, 0, image=img, anchor=tk.NW) canvas.img = img # 保留引用防止被垃圾回收 # 直接在图片上绘制矩形 canvas.create_rectangle(0, 0, 100, 100, fill="blue") # 设置滚动区域为图片大小 canvas.config(scrollregion=(0, 0, img.width(), img.height())) # 布局组件 hor_scroll_bar.pack(fill=tk.X, side=tk.BOTTOM) ver_scroll_bar.pack(fill=tk.Y, side=tk.RIGHT) canvas.pack(fill=tk.BOTH, expand=True) root.mainloop()
思路二:在Frame内添加Canvas承载图片和矩形
如果一定要保留Frame结构,可以在Frame里嵌套一个Canvas,把图片和矩形都画在这个内部Canvas上,确保它们同步滚动:
import tkinter as tk from PIL import ImageTk, Image root = tk.Tk() canvas = tk.Canvas(root) fTable = tk.Frame(canvas) hor_scroll_bar = tk.Scrollbar(root, orient=tk.HORIZONTAL, command=canvas.xview) ver_scroll_bar = tk.Scrollbar(root, orient=tk.VERTICAL, command=canvas.yview) def updateScrollRegion(): canvas.update_idletasks() canvas.config(scrollregion=fTable.bbox()) def createScrollableContainer(): canvas.config(xscrollcommand=hor_scroll_bar.set, yscrollcommand=ver_scroll_bar.set, highlightthickness=0) hor_scroll_bar.config(command=canvas.xview) ver_scroll_bar.config(command=canvas.yview) hor_scroll_bar.pack(fill=tk.X, side=tk.BOTTOM, expand=False) ver_scroll_bar.pack(fill=tk.Y, side=tk.RIGHT, expand=False) canvas.pack(fill=tk.BOTH, side=tk.LEFT, expand=True) canvas.create_window(0, 0, window=fTable, anchor=tk.NW) def addNewLabel(): # 在Frame内创建Canvas承载图片和矩形 inner_canvas = tk.Canvas(fTable) inner_canvas.grid(row=0, column=0) img = ImageTk.PhotoImage(file="test.jpg") inner_canvas.create_image(0, 0, image=img, anchor=tk.NW) inner_canvas.img = img # 在内部Canvas上绘制矩形 inner_canvas.create_rectangle(0, 0, 100, 100, fill="blue") # 设置内部Canvas大小匹配图片 inner_canvas.config(width=img.width(), height=img.height()) updateScrollRegion() createScrollableContainer() addNewLabel() root.mainloop()
内容的提问来源于stack exchange,提问作者Mhmd Admn
相关产品推荐
相关产品推荐

