如何在Tkinter中实现折线图下方放置同尺寸表格图片
Tkinter GUI 表格图片显示问题解决
需求描述
当前基于Tkinter的GUI布局包含:
- 左侧带滚动条的多个径向图表框架
- 上方中间显示折线图的框架
- 下方中间用于展示表格图片的框架
- 右侧显示另一种径向图表的框架
需要实现:
- 表格图片放置在折线图框架的正下方,且两者尺寸保持一致
- 勾选复选框1和2时,同步显示
line_plot_1_2.png与table_1_2.png - 勾选3和4时,切换显示
line_plot_3_4.png与table_3_4.png
修改方案
以下是调整后的完整代码,解决了表格图片的显示问题:
import tkinter as tk from tkinter import ttk from PIL import Image, ImageTk # 创建主窗口 root = tk.Tk() root.title("Radial Charts") root.geometry("1200x800") # 调整窗口高度以容纳上下两个图片 # 创建主框架 main_frame = ttk.Frame(root) main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10) # 左侧带滚动条的径向图表框架 left_frame = ttk.Frame(main_frame) left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) canvas = tk.Canvas(left_frame) canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) scrollbar = ttk.Scrollbar(left_frame, orient=tk.VERTICAL, command=canvas.yview) scrollbar.pack(side=tk.RIGHT, fill=tk.Y) canvas.configure(yscrollcommand=scrollbar.set) canvas.bind('<Configure>', lambda e: canvas.configure(scrollregion=canvas.bbox('all'))) frame = tk.Frame(canvas) canvas.create_window((0, 0), window=frame, anchor=tk.NW) # 中间区域容器:包含折线图和表格图片框架(垂直排列) middle_container = ttk.Frame(main_frame) middle_container.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) # 上方折线图框架 upper_middle_frame = ttk.Frame(middle_container) upper_middle_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True) # 下方表格图片框架 lower_middle_frame = ttk.Frame(middle_container) lower_middle_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True) # 折线图画布 line_plot_canvas = tk.Canvas(upper_middle_frame, background='white') line_plot_canvas.pack(fill=tk.BOTH, expand=True) # 表格图片画布 table_plot_canvas = tk.Canvas(lower_middle_frame, background='white') table_plot_canvas.pack(fill=tk.BOTH, expand=True) # 全局变量 checkbuttons = [] selected_checkbuttons = [] line_plot_image_tk = None table_plot_image_tk = None desired_width = 600 desired_height = 300 # 统一两者高度,确保上下对齐 def generate_plot_path(prefix, start_visit, end_visit): return f"path/{prefix}_{start_visit}_{end_visit}.png" def display_line_plot(image_path): global line_plot_image_tk line_plot_canvas.delete("all") try: image = Image.open(image_path) resized_image = image.resize((desired_width, desired_height), Image.Resampling.LANCZOS) line_plot_image_tk = ImageTk.PhotoImage(resized_image) line_plot_canvas.create_image(0, 0, anchor=tk.NW, image=line_plot_image_tk) # 保持引用防止垃圾回收 line_plot_canvas.image = line_plot_image_tk except Exception as e: print(f"加载折线图失败: {e}") def display_table_plot(image_path): global table_plot_image_tk table_plot_canvas.delete("all") try: image = Image.open(image_path) resized_image = image.resize((desired_width, desired_height), Image.Resampling.LANCZOS) table_plot_image_tk = ImageTk.PhotoImage(resized_image) table_plot_canvas.create_image(0, 0, anchor=tk.NW, image=table_plot_image_tk) # 保持引用防止垃圾回收 table_plot_canvas.image = table_plot_image_tk except Exception as e: print(f"加载表格图片失败: {e}") def checkbox_selected(): selected_checkbuttons.clear() for cb, var in checkbuttons: if var.get() == 1: selected_checkbuttons.append(cb) # 只处理选中恰好两个复选框的情况 if len(selected_checkbuttons) == 2: start_visit = int(selected_checkbuttons[0]["text"].split("_")[1]) end_visit = int(selected_checkbuttons[1]["text"].split("_")[1]) line_path = generate_plot_path("line_plot", start_visit, end_visit) table_path = generate_plot_path("table", start_visit, end_visit) display_line_plot(line_path) display_table_plot(table_path) else: # 选中数量不为2时清空显示 line_plot_canvas.delete("all") table_plot_canvas.delete("all") # 加载左侧径向图表 for i in range(1, 10): image_path = f"path/visit_{i}.png" try: image = Image.open(image_path) image = image.resize((400, 400), Image.Resampling.LANCZOS) image_tk = ImageTk.PhotoImage(image) label = tk.Label(frame, image=image_tk) label.pack(pady=5) label.image = image_tk check_var = tk.IntVar() checkbutton = tk.Checkbutton(label, text=f"visit_{i}", variable=check_var, command=checkbox_selected) checkbutton.place(relx=1, rely=1, anchor=tk.SE) checkbuttons.append((checkbutton, check_var)) except Exception as e: print(f"加载visit_{i}图片失败: {e}") # 启动事件循环 root.mainloop()
关键修改说明
- 布局调整:新增
middle_container框架,将upper_middle_frame和lower_middle_frame放入其中,通过side=tk.TOP实现垂直排列,确保表格在折线图正下方 - 尺寸统一:定义
desired_width和desired_height变量,统一折线图和表格图片的显示尺寸 - 同步显示逻辑:在
checkbox_selected函数中,同时生成折线图和表格图片的路径,调用对应的显示函数同步加载 - 引用保留:在画布上存储图片引用(如
line_plot_canvas.image),避免图片被垃圾回收导致不显示 - 异常处理:添加图片加载异常捕获,方便调试错误
- 窗口高度调整:将主窗口高度从600改为800,确保能完整显示上下两个图片
内容的提问来源于stack exchange,提问作者dsapprentice
相关产品推荐
相关产品推荐

