涉及表格的编程时,都会用上 TreeView 组件,每次写节点移动都要纠结半天,现总结了一下,把这些功能汇总给大家,直接可以拿来就用
特点:支持鼠标多选(需要Shift、Ctrl)键配合多选,然后用鼠标拖动,同时支持用键盘的上、下方向键移动,Home、End 键则为置顶、置底
大家可以直接使用,不费话,上原码:
import tkinter as tk
from tkinter import ttk
def bDown_Shift(event):
tv = event.widget
select = [tv.index(s) for s in tv.selection()]
select.append(tv.index(tv.identify_row(event.y)))
select.sort()
for i in range(select[0],select[-1]+1,1):
tv.selection_add(tv.get_children()[i])
def bDown(event):
tv = event.widget
if tv.identify_row(event.y) not in tv.selection():
tv.selection_set(tv.identify_row(event.y))
def bUp(event):
pass
def bUp_Shift(event):
pass
def bMove(event):
tv = event.widget
i=tv.identify_row(event.y)
if i=="":
return
moveto = tv.index(i)
total=tv.selection()
t1=tv.index(total[0])
t2=tv.index(total[-1])
sel=list(tv.selection())
sel.sort()
if moveto>=t1 and moveto<=t2:
return
if moveto>t2:
for s in sel:
tv.move(s, '', moveto)
else:
for s in reversed( sel):
tv.move(s, '', moveto)
def bDown_Ctrl(event):
#print(11)
tv = event.widget
if tv.identify_row(event.y) not in tv.selection():
tv.selection_add(tv.identify_row(event.y))
def bUp_Ctrl(event):
pass
def keyboard(event):
#print(event.keycode)
tv = event.widget
items=tv.selection()
if event.keycode==38:
musicMoveUp()# 上移
elif event.keycode==40:
musicMoveDown()# 下移
elif event.keycode==36:
musicMoveTop()# Home 置顶
elif event.keycode==35:
musicMoveBottom() # End 置底
def musicMoveUp():#上移
items=tree.selection() #选择的总数
if len(items)==0:
return
intConnect=0#连接计数,即选中的在最前面的连续数
intCount=0 #选中计数器
for item in items:
intIndex=tree.index(item)
if intConnect==intIndex:
intConnect=intConnect+1
intCount=intCount+1#选中计数器
if intIndex>0 and tree.index(items[-1])+1>len(items) and intConnect!=intCount:
tree.move(item,'',intIndex-1)
#
def musicMoveTop():#置顶
#if tree.curselection():#是否存在选择中项目
items=tree.selection() #选择的总数
if len(items)==0:
return
for item in reversed(items): #倒序
intIndex=tree.index(item)
if intIndex>0:
tree.move(item,tree.parent(item),0)
tree.see(item)
#
def musicMoveDown():#下移
items=tree.selection() #选择的总数
if len(items)==0:
return
item=items[0] #取第1个选中的来得到该树枝的子项目数
intTotalChildren=len(tree.get_children(tree.parent(item)))
intConnect=intTotalChildren-1#连接计数,即选中的在最后面的连续数
intCount=intTotalChildren-1 #选中计数器
for item in reversed(items): #倒序
intIndex=tree.index(item)
if intConnect==intIndex:
intConnect=intConnect-1
intCount=intCount-1#选中计数器
if intIndex<intTotalChildren and tree.index(items[0])+len(items)<intTotalChildren and intConnect!=intCount:
tree.move(item,'',intIndex+1)
def musicMoveBottom():#置底
items=tree.selection() #选择的总数
if len(items)==0:
return
intTotalChildren=len(tree.get_children(tree.parent(items[0])))
for item in items:
intIndex=tree.index(item)
if intIndex<intTotalChildren-1:
tree.move(item,tree.parent(item),tk.END)
tree.see(item)
root = tk.Tk()
tree = ttk.Treeview(columns=("col1","col2"),
displaycolumns="col2",
selectmode='none')
for i in range(10):
tree.insert('', 'end',iid='line%i' % i, text='line:%s' % i, values=('', i))
tree.grid()
tree.bind("<ButtonPress-1>",bDown)
tree.bind("<ButtonRelease-1>",bUp)#, add='+')
tree.bind("<B1-Motion>",bMove)#, add='+')
tree.bind("<Shift-ButtonPress-1>",bDown_Shift)#, add='+')
tree.bind("<Shift-ButtonRelease-1>",bUp_Shift)#, add='+')
tree.bind("<Control-ButtonPress-1>",bDown_Ctrl)#, add='+')
tree.bind("<Control-ButtonRelease-1>",bUp_Ctrl)#, add='+'
tree.bind('<Key>',keyboard)
root.mainloop()