Python使用Tkinter实现按钮显示图片功能异常
问题解决:Tkinter按钮图片显示异常与页面跳转失效
问题分析
你遇到的两个问题根源分别是:
- 图片仅显示边框:局部变量中的
PhotoImage对象被Python垃圾回收,Tkinter无法维持图片引用;或当前Tk版本不支持PNG格式加载。 - 页面跳转失效:代码中存在笔误(
patient_page的Label文本含多余反引号),同时图片加载异常可能导致按钮交互区域异常。
解决方案
1. 修复图片显示问题
情况1:Tk版本支持PNG(Python 3.6+ 通常对应Tk 8.6+)
- 将图片对象绑定到按钮的属性上,避免被垃圾回收
- 若需同时显示按钮文本与图片,添加
compound参数指定两者位置(如compound="top"表示图片在上,文本在下)
情况2:Tk版本不支持PNG
- 安装
Pillow库扩展图片支持:pip install pillow - 使用
Pillow的ImageTk加载图片
2. 修复页面跳转问题
- 移除
patient_page中Label文本的多余反引号 - 确保图片路径正确(
./patient_navigate.png需在脚本运行的当前目录下)
修改后的完整代码
import tkinter as tk # 若需Pillow支持,取消下方注释并安装Pillow # from PIL import Image, ImageTk class main_window(tk.Tk): def __init__(self, *args, **kwargs): tk.Tk.__init__(self, *args, **kwargs) self.title("HMS") container = tk.Frame(self) container.pack(side="top", fill="both", expand=True) container.grid_rowconfigure(0, weight=1) container.grid_columnconfigure(0, weight=1) self.frames = {} for F in (landing_page, patient_page): frame = F(container, self) self.frames[F] = frame frame.grid(row=0, column=0, sticky="nsew") self.show_frame(landing_page) def show_frame(self, cont): frame = self.frames[cont] frame.tkraise() class landing_page(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) label = tk.Label(self, text="Hospital Management") label.pack(pady=10, padx=10) # 标准Tkinter加载PNG(支持的情况) patient_icon = tk.PhotoImage(file='./patient_navigate.png') # 若使用Pillow,替换为下方代码 # img = Image.open('./patient_navigate.png') # patient_icon = ImageTk.PhotoImage(img) button = tk.Button( self, text="Patient Page", image=patient_icon, compound="top", # 同时显示图片和文本的位置设置 command=lambda: controller.show_frame(patient_page) ) button.patient_icon = patient_icon # 绑定图片对象到按钮属性,避免垃圾回收 button.pack() class patient_page(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) # 移除多余的反引号 label = tk.Label(self, text="Patient Page") label.pack(pady=10, padx=10) button1 = tk.Button( self, text="Back to Home", command=lambda: controller.show_frame(landing_page) ) button1.pack() app = main_window() app.mainloop()
内容的提问来源于stack exchange,提问作者Shaji Sivaraman
相关产品推荐
相关产品推荐

