Skip to content

TreeView

TreeView 组件是一个树状结构和表格的结合体。第一列是树状结构,后几列是列表。每一行表示一个 item,树的 item 可以分级,每个 item 有子 item,名称对应 text 标签。每一行的值用 values 元组里的值表示。

image-20210221162253394

item 有 5 个标签,分别是:textimagevaluesopentags

参数说明

1、TreeView 参数:

参数作用
columns值是一个列表。列表里每个元素代表一个列标识符的名称。列表的长度为列的长度。
displaycolumns列表,这里的元素是列表符,表示的是哪些列可以显示以及顺序,或者用 ‘#all’ 表示全部显示
height表示要显示几行数据(注意:这个部件的宽度是根据列的多少自动定义的)
padding填充,是个最多4个元素的列表
selectmode定义如何去选择一行。"extended" 是可选多行(用 Ctrl + 鼠标), “browse” 是只能选一行, “none" 是不能改变选择,默认是 "extended”
show表示这个部件显示哪种功能,“tree” 表示仅显示第一列(单树模式),“headings” 表示显示除一列的其他列(单列表模式),默认是 "tree headings",显示所有列。注意,‘#0’(第一列)是永远存在的

2、item 参数:

选项描述
text树状结构这边的名称。
image树状结构这边的名称的左边加个图。
values列表结构这边每一行的值,values未赋值的列会为空值,超过列的长度会被截断。
open布尔值,代表子item的显示打开或关闭
tags与item关联的标记

3、tag 参数

选项描述
foreground前景色
background背景色
font字体
image

方法列表:

  • bbox(item, column=None)

    返回一个 item 的范围(x, y, width, height),如果 column 指定了一个列,则返回一个元素范围,如果 item 不可视,则返回空值。

  • get_children(item=None)

    返回一个 item 的所有子 item ,这个子 item 是一个列表形式,如果 item 没指定,则返回根目录的 item

  • set_children(item, *newchildren)

    设置一个 item 的新子 item 。这里设置了之后实际是全部替换

  • column(column, option=None, **kw)

    给各列设置属性,或返回属性。

    第一个 column 是列标识符

    第二个 option,如果不设置则返回所有属性的字典,如果设置则返回那个属性的值。

    kw 里的 option 有5个

    • id:只读属性,返回列名。
    • anchor:文字在cell里的对齐方式,标准的tk的anchor属性
    • minwidth: 值,单位是像素,列的最小宽度
    • stretch: 布尔值,表示列的宽度是否随整个部件的改动而变化。
    • width:列宽,单位是像素。
    • 提示:如果要设置树状结构那列,用 column="#0"
  • delete(*items)

    删除 item 及其子 item

  • detach(*items)

    断开 item 及其子 item ,这里的断开只是不显示,以后还可以链接起来。

  • exists(item)

    返回 True ,如果 item 在树里。

  • focus(item=None)

    如果不指定 item,则返回当前获得焦点的 item,如果指定 item,则让该 item 获得焦点。若无则返回空值。

  • heading(column, option=None, **kw)

    查询或修改指定列的标题选项

    第一个 column 是列标识符

    第二个 option,如果不设置则返回所有属性的字典,如果设置则返回那个属性的值。

    kw 里的 option 有4个

    • text:列头名
    • image: 列头名右的图像
    • anchor:文字在 heading 里的对齐方式,标准的 tkanchor 属性
    • command:点击列头的回调函数
  • insert(parent, index, iid=None, **kw)

    创建新 item 并返回新创建 item 的项标识符。

    • parent:用 item ID 表示父 item,或者 '' 表示根 item
    • index:数值 int,或 'end',表示 item 插入的位置
    • iiditem 标识符,可自动生成
    • kw:看上面的 Item Options 介绍。
  • item(item, option=None, **kw)

    查询或修改指定 item 的选项

  • selection(selop=None, items=None)

    如果没指定 selop 则返回所有选中的 items,列表形式,若 selop 指定了 selection methods,则相应 act

  • set(item, column=None, value=None)

    指定 item,如果不设定 columnvalue,则返回他们的字典,如果设定了 column,则返回该 columnvalue ,如果 value 也设定了,则作相应更改。

TreeView 可选事件和方法

  • <<TreeviewSelect>>,代表选择变化时发生
  • <<TreeviewOpen>>itemopen=True 时发生
  • <<TreeviewClose>>itemopen=False 时发生

提示: 可用 Treeview.focus()Treeview.selection() 可获取 itemitems.

案例:显示数据

python
import tkinter as tk
from tkinter import ttk

# 准备数据
students = [
    {"name": "李四", "chinese": 50, "math": 40, "english": 30, "total": 120},
    {"name": "王五", "chinese": 100, "math": 100, "english": 100, "total": 300}
]

root = tk.Tk()
root.geometry('500x300')

# 提前准备列标签名字与中文显示内容
columns = ("name", "chinese", "math", "english")
columns_value = ('姓名', '语文', '数学', '英语')

# 使用 ttk 创建一个树状图
tree_view = ttk.Treeview(root, height=18, show="headings", columns=columns)

# 设置列名
tree_view.column('name', width=80, anchor='center')
tree_view.column('chinese', width=80, anchor='center')
tree_view.column('math', width=80, anchor='center')
tree_view.column('english', width=80, anchor='center')

# 给列名设置显示的名字
tree_view.heading('name', text='姓名')
tree_view.heading('chinese', text='语文')
tree_view.heading('math', text='数学')
tree_view.heading('english', text='英语')

tree_view.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

# 往树状图中插入数据
for index, stu in enumerate(students):
    tree_view.insert('', index + 1, values=(stu['name'], str(stu['chinese']), str(stu['math']), str(stu['english'])))

# 进入消息循环
root.mainloop()

给标题添加排序事件

py
import tkinter as tk
from tkinter import ttk

students = [
    {"name": "李四", "chinese": 50, "math": 40, "english": 30, "total": 120},
    {"name": "王五", "chinese": 100, "math": 100, "english": 100, "total": 300}
]

root = tk.Tk()
root.geometry('500x300+1300+300')
columns = ("name", "chinese", "math", "english")
columns_value = ('姓名', '语文', '数学', '英语')
# 表格
tree_view = ttk.Treeview(root, height=18, show="headings", columns=columns)

tree_view.column('name', width=80, anchor='center')
tree_view.column('chinese', width=80, anchor='center')
tree_view.column('math', width=80, anchor='center')
tree_view.column('english', width=80, anchor='center')
tree_view.heading('name', text='姓名')
tree_view.heading('chinese', text='语文')
tree_view.heading('math', text='数学')
tree_view.heading('english', text='英语')

tree_view.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

for index, stu in enumerate(students):
    tree_view.insert('', index + 1, values=(stu['name'], str(stu['chinese']), str(stu['math']), str(stu['english'])))


def tree_view_sort_column(tv, col_name, reverse):
    print(tv, col_name, reverse)
    """
    tv: treeviewe 组件
    col: column 列对象
    reverse: 是否逆序
    """
    # Tree view、列名、排列方式
    # 使用列表推导式获取搜有的 tree view 字元素
    rows = [(tv.set(k, col_name), k) for k in tv.get_children('')]
    print('get_children -> k: ', tv.get_children(''))
    print('rows', rows)
    # 获取对象的
    # 排序方式
    rows.sort(reverse=reverse)
    # 根据排序后索引移动
    for index, (val, k) in enumerate(rows):
        tv.move(k, '', index)

    # 给当前元素重新绑定事件,使之成为再点倒序的标题
    tv.heading(col, command=lambda: tree_view_sort_column(tv, col_name, not reverse))


for col in columns:
    # 给所有列添加事件
    tree_view.heading(col, command=lambda col_name=col: tree_view_sort_column(tree_view, col_name, False))

# 进入消息循环
root.mainloop()

数据节点添加事件

py
import tkinter as tk
from tkinter import ttk

students = [{"name": "李四", "chinese": 50, "math": 40, "english": 30, "total": 120},
            {"name": "王五", "chinese": 100, "math": 100, "english": 100, "total": 300}]

root = tk.Tk()
root.geometry('500x300+100+100')

# 1. 创建字段
columns = ("name", "chinese", "math", "english")
columns_value = ('姓名', '语文', '数学', '英语')

# 2. 创建表格对象
tree_view = ttk.Treeview(root, show="headings", columns=columns)

# 3. 给表格添加字段名
tree_view.column('name', width=80, anchor='center')
tree_view.column('chinese', width=80, anchor='center')
tree_view.column('math', width=80, anchor='center')
tree_view.column('english', width=80, anchor='center')

# 4. 设置字段在页面上显示的内容
tree_view.heading('name', text='姓名')
tree_view.heading('chinese', text='语文')
tree_view.heading('math', text='数学')
tree_view.heading('english', text='英语')

# 5. 将表格对象布局到页面上
tree_view.pack(fill=tk.BOTH, expand=True)

# 6. 往表格中添加数据
for index, stu in enumerate(students):
    tree_view.insert('', index + 1, values=(stu['name'], str(stu['chinese']), str(stu['math']), str(stu['english'])))


def tree_view_click(event):
    # 7.1 遍历选中的元素
    for item in tree_view.selection():
        # 获取选中元素的值
        item_text = tree_view.item(item, "values")
        # 打印选中元素的值
        print(item_text)


# 7. 单击事件 获取当前点击行的值
# 鼠标左键抬起 点击触发事件 可以重复触发
tree_view.bind('<ButtonRelease-1>', tree_view_click)


# 鼠标选中一行回调
def select_tree(event):
    print(event)
    for item in tree_view.selection():
        item_text = tree_view.item(item, "values")
        print(item_text)


# 8. 选中行事件
tree_view.bind('<<TreeviewSelect>>', select_tree)


def del_select():
    for item in tree_view.selection():
        tree_view.delete(item)


# 9. 删除表格元素
del_btn = tk.Button(root, text='删除')
del_btn.pack()
# 9.2 配置删除事件
del_btn.config(command=del_select)

# 进入消息循环
root.mainloop()

树状结构展示数据

image-20210221162218190

python
import tkinter as tk
from tkinter import ttk

root = tk.Tk()

root.geometry("500x300")

# 定义列的名称,选中用什么方式展示数据
tree = ttk.Treeview(root, show="tree")

# ""表示父节点是根
country_1 = tree.insert("", 0, "中国", text="中国China", values=("1",))
# text表示显示出的文本,values是隐藏的值
city1 = tree.insert(country_1, 0, "广东", text="中国广东", values=("2",))
city2 = tree.insert(country_1, 1, "江苏", text="中国江苏", values=("3",))


country_2 = tree.insert("", 1, "美国", text="美国USA", values=("4",))
city3 = tree.insert(country_2, 0, "加州", text="美国加州", values=("5",))


# 鼠标选中一行回调
def select_tree(event):
    for item in tree.selection():
        item_text = tree.item(item, "text")
        print(item_text)
        item_text = tree.item(item, "values")
        print(item_text)


# 选中行
tree.bind('<<TreeviewSelect>>', select_tree)
tree.pack(expand=True, fill=tk.BOTH)

root.mainloop()