
在tkinter中展示结构化的表格数据,特别是从数据库中查询到的结果,是一个常见的需求。初学者可能会尝试使用多个entry或label组件通过grid布局来模拟表格。然而,这种方法存在诸多弊端:
为了解决这些问题,Tkinter的ttk(Themed Tkinter)模块提供了专门用于显示表格和树状数据的Treeview组件。ttk.Treeview是构建专业级数据表格界面的首选。
ttk.Treeview组件能够以表格或树状结构显示数据。对于表格数据,其核心思想是将数据组织成行和列,并允许用户自定义列标题、宽度和对齐方式。
下面我们将通过一个具体的示例来演示如何使用ttk.Treeview从模拟数据(通常是数据库查询结果的格式)构建一个动态表格。
首先,我们需要导入tkinter和ttk模块。为了演示,我们使用一个列表嵌套字典的结构来模拟从数据库(如Supabase)获取的数据,这种格式非常常见且易于处理。
from tkinter import *
from tkinter import ttk
# 模拟从数据库获取的数据
# 实际应用中,response.data 会是类似这样的结构
response_data = [
{"id": 1, "name": "Afghanistan", "code": "AFG"},
{"id": 2, "name": "Albania", "code": "ALB"},
{"id": 3, "name": "Algeria", "code": "DZA"},
{"id": 4, "name": "Andorra", "code": "AND"},
{"id": 5, "name": "Angola", "code": "AGO"},
]
# 动态获取列名
# 这通常是数据中第一个字典的所有键
if response_data:
cols = list(response_data[0].keys())
else:
cols = [] # 如果数据为空,则没有列说明:
创建主应用程序窗口。
root = Tk()
root.title("数据表格示例")
root.geometry("600x400")创建Treeview实例,并指定列名和显示方式。
# 创建一个Treeview组件 # columns参数指定了表格的列标识符 # show="headings"表示只显示列标题,不显示默认的树状结构 tree = ttk.Treeview(root, columns=cols, show="headings") tree.pack(fill="both", expand=True, padx=10, pady=10) # 使用pack布局,填充整个窗口
遍历列名列表,为每一列设置标题文本和宽度、对齐方式等属性。
# 为每一列设置标题和属性
for col in cols:
tree.heading(col, text=col) # 设置列标题为列名本身
tree.column(col, width=120, anchor="center") # 设置列宽和居中对齐遍历模拟数据中的每一行,将每行数据作为Treeview的一个item插入。
# 插入数据
for item in response_data:
# tree.insert("", "end", values=list(item.values()))
# "" 表示根节点
# "end" 表示插入到最后
# values 参数是一个列表,包含当前行所有列的值,顺序与columns参数一致
tree.insert("", "end", values=[item[key] for key in cols])注意: values=[item[key] for key in cols] 确保了数据值是按照 cols 列表中的列顺序提供的,这对于动态列非常重要。如果直接使用 list(item.values()),则字典的迭代顺序可能不固定(尽管在Python 3.7+中字典保持插入顺序,但为了健壮性,显式指定顺序更佳)。
启动Tkinter事件循环,使窗口显示并响应用户操作。
root.mainloop()
将上述步骤整合,得到完整的Tkinter数据表格示例:
from tkinter import *
from tkinter import ttk
# 模拟从数据库获取的数据
# 实际应用中,response.data 会是类似这样的结构
response_data = [
{"id": 1, "name": "Afghanistan", "code": "AFG"},
{"id": 2, "name": "Albania", "code": "ALB"},
{"id": 3, "name": "Algeria", "code": "DZA"},
{"id": 4, "name": "Andorra", "code": "AND"},
{"id": 5, "name": "Angola", "code": "AGO"},
{"id": 6, "name": "Argentina", "code": "ARG"},
{"id": 7, "name": "Armenia", "code": "ARM"},
{"id": 8, "name": "Australia", "code": "AUS"},
{"id": 9, "name": "Austria", "code": "AUT"},
{"id": 10, "name": "Azerbaijan", "code": "AZE"},
]
# 动态获取列名
if response_data:
cols = list(response_data[0].keys())
else:
cols = []
# 创建应用程序窗口
root = Tk()
root.title("国家信息列表")
root.geometry("600x400")
# 创建一个Treeview组件
tree = ttk.Treeview(root, columns=cols, show="headings")
# 为每一列设置标题和属性
for col in cols:
tree.heading(col, text=col.capitalize()) # 将列名首字母大写作为标题
tree.column(col, width=150, anchor="center")
# 插入数据
for item in response_data:
tree.insert("", "end", values=[item[key] for key in cols])
# 添加垂直滚动条
vsb = ttk.Scrollbar(root, orient="vertical", command=tree.yview)
tree.configure(yscrollcommand=vsb.set)
# 布局Treeview和滚动条
tree.pack(side="left", fill="both", expand=True, padx=10, pady=10)
vsb.pack(side="right", fill="y", padx=(0, 10), pady=10)
# 运行主循环
root.mainloop()在实际应用中,您会使用数据库客户端库(如supabase-py、psycopg2、sqlite3等)来获取数据。无论使用哪种库,关键在于将查询结果转换为ttk.Treeview期望的格式:一个包含字典的列表,其中每个字典代表一行数据,字典的键是列名。
例如,如果您使用Supabase,response.data通常会返回一个列表,其中每个元素是一个字典,完美符合Treeview的要求。
# 假设这是您从Supabase获取数据的方式
# from supabase import create_client, Client
# url: str = "YOUR_SUPABASE_URL"
# key: str = "YOUR_SUPABASE_KEY"
# supabase: Client = create_client(url, key)
# response = supabase.table('pdvList').select('*').execute()
#
# response_data = response.data # 这就是您需要的数据
# 接下来的步骤与示例代码相同:
# if response_data:
# cols = list(response_data[0].keys())
# else:
# cols = []
# ... 创建Treeview,配置列,插入数据 ...ttk.Treeview是Tkinter中显示表格数据的强大而高效的组件。它不仅解决了传统方法中性能和布局的诸多问题,还提供了丰富的内置功能,使得开发人员能够轻松构建出专业、交互性强的表格界面。通过本文的详细教程和示例代码,您应该已经掌握了使用ttk.Treeview从数据库动态加载并展示数据的核心方法。
以上就是构建Tkinter数据库数据显示表格:ttk.Treeview深度指南的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号