如何为Tkinter表格添加表头、滚动条及显示网格线?
解决Tkinter表格的滚动条、表头和网格线问题
下面是修改后的代码,已实现你需要的三个功能:添加垂直滚动条、显示固定表头、显示网格线。
修改要点说明
- 表头:在第0行添加带样式的表头标签,用背景色和加粗字体区分数据行
- 滚动条:通过
Canvas嵌套Frame的方式实现滚动区域(Tkinter原生Frame不支持滚动) - 网格线:给所有控件添加边框属性模拟网格效果
import tkinter as tk class Example(tk.Frame): def __init__(self, parent): tk.Frame.__init__(self, parent) b = tk.Button(self, text="Done!", command=self.upload_cor) b.pack(side="top", pady=5) # 创建滚动容器 container = tk.Frame(self) container.pack(side="top", fill="both", expand=True) # 垂直滚动条 scrollbar = tk.Scrollbar(container) scrollbar.pack(side="right", fill="y") # 画布承载表格内容 canvas = tk.Canvas(container, yscrollcommand=scrollbar.set) canvas.pack(side="left", fill="both", expand=True) scrollbar.config(command=canvas.yview) # 表格内容框架 table = tk.Frame(canvas) canvas.create_window((0, 0), window=table, anchor="nw") # 定义表头文本 headers = ["Row ID", "Reviewer", "Task", "Correction", "Seconds", "Start Time", "End Time"] # 创建表头标签 for col, header in enumerate(headers): label = tk.Label(table, text=header, bg="#f0f0f0", bd=1, relief="solid", padx=5, pady=2, font=("Arial", 9, "bold")) label.grid(row=0, column=col, sticky="nsew") data = ( (45417, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"), (45418, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"), (45419, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"), (45420, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"), (45421, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"), (45422, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"), (45423, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"), # 额外添加数据测试滚动 (45424, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"), (45425, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"), ) self.widgets = {} row = 0 for rowid, reviewer, task, num_seconds, start_time, end_time in data: row += 1 self.widgets[rowid] = { "rowid": tk.Label(table, text=rowid, bd=1, relief="solid", padx=5, pady=2), "reviewer": tk.Label(table, text=reviewer, bd=1, relief="solid", padx=5, pady=2), "task": tk.Label(table, text=task, bd=1, relief="solid", padx=5, pady=2), "num_seconds_correction": tk.Entry(table, bd=1, relief="solid"), "num_seconds": tk.Label(table, text=num_seconds, bd=1, relief="solid", padx=5, pady=2), "start_time": tk.Label(table, text=start_time, bd=1, relief="solid", padx=5, pady=2), "end_time": tk.Label(table, text=end_time, bd=1, relief="solid", padx=5, pady=2) } self.widgets[rowid]["rowid"].grid(row=row, column=0, sticky="nsew") self.widgets[rowid]["reviewer"].grid(row=row, column=1, sticky="nsew") self.widgets[rowid]["task"].grid(row=row, column=2, sticky="nsew") self.widgets[rowid]["num_seconds_correction"].grid(row=row, column=3, sticky="nsew") self.widgets[rowid]["num_seconds"].grid(row=row, column=4, sticky="nsew") self.widgets[rowid]["start_time"].grid(row=row, column=5, sticky="nsew") self.widgets[rowid]["end_time"].grid(row=row, column=6, sticky="nsew") # 配置列宽自适应 for col in range(len(headers)): table.grid_columnconfigure(col, weight=1) # 更新画布滚动区域范围 table.update_idletasks() canvas.config(scrollregion=canvas.bbox("all")) # 绑定鼠标滚轮事件(兼容Windows/Linux) def on_mousewheel(event): canvas.yview_scroll(int(-1*(event.delta/120)), "units") canvas.bind_all("<MouseWheel>", on_mousewheel) canvas.bind_all("<Button-4>", lambda e: canvas.yview_scroll(-1, "units")) canvas.bind_all("<Button-5>", lambda e: canvas.yview_scroll(1, "units")) def upload_cor(self): for rowid in sorted(self.widgets.keys()): entry_widget = self.widgets[rowid]["num_seconds_correction"] new_value = entry_widget.get() print("%s: %s" % (rowid, new_value)) if __name__ == "__main__": root = tk.Tk() root.title("Tkinter Table Demo") root.geometry("800x400") Example(root).pack(fill="both", expand=True) root.mainloop()
核心功能细节
滚动实现:
- 用
Canvas作为滚动载体,内部嵌套表格Frame - 关联滚动条与画布的滚动命令,实现同步滚动
- 添加鼠标滚轮支持,适配不同操作系统的滚轮事件
- 用
表头设计:
- 表头固定在第0行,通过背景色和字体样式与数据行区分
- 表头列与数据列使用相同的网格配置,保证对齐
网格线效果:
- 给所有标签和输入框添加
bd=1(边框宽度)和relief="solid"(实线边框)属性,形成网格视觉效果
- 给所有标签和输入框添加
内容的提问来源于stack exchange,提问作者TourEiffel
相关产品推荐
相关产品推荐

