如何让Canvas中create_image生成的图片显示在Tkinter控件上层
问题原因
Tkinter 遵循固定的控件层级规则:直接挂载在父窗口上的独立控件(如你代码里的 Entry、Button),层级永远高于 Canvas 内部通过 create_image/create_rectangle 等方法绘制的图元。因此你在 Canvas 中绘制的 alert 图片不可能覆盖放在主窗口上的两个控件。
另外你原有代码存在笔误:alert_panel resize 后生成的对象,在转 PhotoImage 时错误传入了未定义的 panel 变量,会导致 alert 图片无法正常加载。
解决方案1:将控件嵌入Canvas(适配原有需求)
使用 Canvas 提供的 create_window 方法,把 Entry 和 Button 嵌入到 Canvas 内部,使其成为 Canvas 内部元素,后续绘制的图片默认层级就会高于这些嵌入控件。
修正后的完整代码如下:
from tkinter import * from PIL import Image, ImageTk w = Tk() canvas = Canvas(width = 800, height = 800) canvas.place(relx=0, rely=0) background = Image.open("light.jpg").resize((700,700)) background = ImageTk.PhotoImage(background) canvas.create_image(0,0,image=background,anchor=NW) # 修正笔误:PhotoImage传入正确的alert_panel对象 alert_panel = Image.open("alert_panel.png").resize((500,300)) alert_panel = ImageTk.PhotoImage(alert_panel) def login(): # 此时绘制的图片层级默认高于之前嵌入的控件 alert = canvas.create_image(100,200,image=alert_panel,anchor=NW) # 创建控件时指定父容器为canvas entry = Entry(canvas, fg="black", bg="light gray") entry.configure(highlightbackground="black", highlightcolor="black") entry.insert(0,"Username:") # 用create_window将控件嵌入canvas对应位置,坐标对应原有relx/rely换算后的像素值 canvas.create_window(160, 136, window=entry) buton1 = Button(canvas, text="L O G I N", highlightbackground="black", command=login) # 坐标对应原有rely=0.27换算后的像素值 0.27*800=216 canvas.create_window(264, 216, window=buton1) w.mainloop()
解决方案2:使用顶层窗口实现弹窗
如果不想改动原有控件的放置逻辑,可以将alert做成独立的顶层窗口,设置置顶属性即可覆盖主窗口所有控件,示例逻辑如下:
def login(): alert_win = Toplevel(w) alert_win.overrideredirect(True) # 去掉窗口标题栏 alert_win.geometry("500x300+100+200") # 使弹窗始终显示在主窗口上方 alert_win.attributes("-topmost", True) # 在弹窗里放置alert_panel图片即可 alert_label = Label(alert_win, image=alert_panel) alert_label.pack()
内容的提问来源于stack exchange,提问作者newfile.py
相关产品推荐
相关产品推荐

