如何在带有X、Y轴滚动条的tkinter窗口中设置PNG图片作为背景
实现带滚动条的tkinter窗口显示PNG背景的可行方案
核心问题原因
你遇到的显示异常主要来自三个错误:
- 原有滚动窗口的水平滚动条配置错误、Frame锚点配置错误
- 承载控件的Frame默认填充不透明底色,直接覆盖了下层的背景内容
- Tkinter的
PhotoImage对象没有保留强引用,被Python垃圾回收后图片直接消失
完整可运行代码
from tkinter import * from tkinter import ttk def win(): r0 = Tk() r0.title('带背景的滚动窗口') r0.geometry('800x800') f = Frame(r0, bg='BLACK') f.pack(fill=BOTH, expand=1) # 创建滚动用Canvas c = Canvas(f, bg='BLACK') c.pack(side=LEFT, fill=BOTH, expand=1) # 加载并绘制背景图,保留引用避免被回收 bg = PhotoImage(file="Your_img.png") c.create_image(0, 0, image=bg, anchor="nw") c.bg_img = bg # 核心:给Canvas加属性保留图片引用 # 滚动条配置(修正原代码水平滚动条绑定错误) s1 = ttk.Scrollbar(f, orient=VERTICAL, command=c.yview) s2 = ttk.Scrollbar(f, orient=HORIZONTAL, command=c.xview) s1.pack(side=RIGHT, fill=Y) c.configure(yscrollcommand=s1.set) s2.pack(side=BOTTOM, fill=X) c.configure(xscrollcommand=s2.set) # 修正:绑定到水平滚动条s2 # 鼠标滚动绑定 def mw(event): c.yview_scroll(-1*int((event.delta/120)), 'units') c.bind_all('<MouseWheel>', mw) # 创建承载控件的Frame,如果不需要透明可以自行设置bg底色 r = Frame(c, bg='') # 修正原代码锚点为nw,保证Frame从Canvas左上角开始放置 c.create_window((0,0), window=r, anchor='nw') # 测试:在Frame里添加控件,设置背景和背景图适配 test_label = Label(r, text='测试文本', width=20, height=5, bg='white') test_label.pack(pady=20, padx=20) test_btn = ttk.Button(r, text='测试按钮') test_btn.pack(pady=20) # 可以继续添加其他控件,不需要调整背景逻辑 c.bind('<Configure>', lambda e: c.configure(scrollregion=c.bbox('all'))) return r, r0 if __name__ == '__main__': r, r0 = win() r0.mainloop()
关键说明
- 如果你的PNG图片不带透明通道,完全不需要引入PIL模块,原生Tkinter的
PhotoImage即可正常加载 - 如果需要使用带透明通道的PNG,仅需安装pillow库(执行
pip install pillow),导入from PIL import Image, ImageTk,将图片加载逻辑替换为bg = ImageTk.PhotoImage(Image.open("Your_img.png"))即可;路径报错一般是使用了相对路径,换成绝对路径或者将图片和脚本放在同一目录就能解决 - 如果需要背景固定不跟随滚动,只需要绑定Canvas的滚动事件,每次滚动时调整背景图的坐标即可
内容的提问来源于stack exchange,提问作者Я J K
相关产品推荐
相关产品推荐

