Tkinter Treeview 排序
在创建Treeview控件后,有一个很常见的功能是将栏目信息做排序,通常是可以单击栏位标题就可以执行排序,本节将以实例讲解这方面的应用。
示例1
排序Treeview控件State栏的数据,在这个程序中为了简化程序,省略了图标栏。所以Treeview控件只有一个State栏,当单击栏标题时可以正常排序(由小到大),如果再单击可以反向排序,排序方式将如此切换。
from tkinter import *
from tkinter.ttk import *
def treeview_sortColumn(col):
global reverseFlag # 定义排序标识全局变量
lst = [(tree.set(st,col),st)
for st in tree.get_children("")]
print(lst) # 打印列表
lst.sort(reverse=reverseFlag) # 排序列表
print(lst) # 打印列表
for index, item in enumerate(lst): # 重新移动项目内容
tree.move(item[1],"",index)
reverseFlag = not reverseFlag # 更改排序标识
root = Tk()
root.title("apidemos.com")
reverseFlag = False # False # 排序标识注明是否反向排序
myStates = {"Illinois","California","Texas","Washington",
"Jiangsu","Shandong","Guangdong","Fujian",
"Mississippi","Kentucky","Florida","Indiana"}
tree = Treeview(root,columns=("states"),show="headings")
yscrollbar = Scrollbar(root) # y轴scrollbar对象
yscrollbar.pack(side=RIGHT,fill=Y) # y轴scrollbar包装显示
tree.pack()
yscrollbar.config(command=tree.yview) # y轴scrollbar设置
tree.configure(yscrollcommand=yscrollbar.set)
# 建立栏标题
tree.heading("states",text="State")
# 建立内容
for state in myStates:
tree.insert("",index=END,values=state) # tree.insert("",index=END,values=(state,))
# 单击标题栏将启动treevi_sortColumn
tree.heading("#1",text="State",
command=lambda c="states": treeview_sortColumn(c))
# tree.heading("#1",text="State",command=lambda : treeview_sortColumn("states"))
root.mainloop()
输出:
这个程序为了简单,省略显示图标栏,在第23行创建Treeview控件时增加了show="headings"参数。
tree = Treeview(root,columns=("states"),show="headings")
第32、33行是建立栏位的数据,相当于将myStates列表数据放入Treeview控件。接下来第34、35行是重点,这其实是heading( )方法,所以是一条命令,只是因为太长分为两行撰写。当用鼠标单击标题栏时会执行command所指定的方法,这是Lambda表达式,将“states”设置给变量c,然后将c当作参数传递给treeview_sortColumn( )方法。
程序第4~13行是treeview_sortColumn( )方法,在这个方法中为了让读者了解数据内容特别在第8和10行列出目前列表内容,方便读者了解目前程序的意义。首先第5行设置reverseFlag是全局变量,它的原始定义在17行。第6、7行其实是同一条命令,如下所示。
lst = [(tree.set(st,col),st)
for st in tree.get_children("")]
上述有一个get_children( )方法,它的语法如下。
get_children([item])
它会传回item的一个tuple的iid值,如果省略则是得到一个tuple,此tuple是top-level的iid值。
上述程序主要是建立lst列表,第8行会打印这个列表内容,可以在Python Shell窗口看到,如下所示。
[('Shandong', 'I001'), ('Indiana', 'I002'), ('Kentucky', 'I003'), ('Texas', 'I004'), ('Fujian', 'I005'), ('Florida', 'I006'), ('Guangdong', 'I007'), ('Jiangsu', 'I008'), ('Mississippi', 'I009'), ('California', 'I00A'), ('Washington', 'I00B'), ('Illinois', 'I00C')]
第9行是将上述列表内容排序,第10行是列出排序结果,如下所示。
[('California', 'I00A'), ('Florida', 'I006'), ('Fujian', 'I005'), ('Guangdong', 'I007'), ('Illinois', 'I00C'), ('Indiana', 'I002'), ('Jiangsu', 'I008'), ('Kentucky', 'I003'), ('Mississippi', 'I009'), ('Shandong', 'I001'), ('Texas', 'I004'), ('Washington', 'I00B')]
第11、12行内容如下。
for index, item in enumerate(lst): # 重新移动项目内容
tree.move(item[1],"",index)
其中有一个move( )方法,语法如下。
remove(iid, parent, index)
将iid所指项目移至parent层次的index位置,此程序用“”代表parent层次。第13行是更改排序标识,这样下次就可以使用反向排序。