——高级树状图)
tkinter绘制组件50——高级树状图引言节点元素高级树状图控件获取当前选中元素添加节点删除节点重命名节点折叠、展开所有事件绑定面板布局效果github项目pip下载引言在tkinter绘制组件36——树状图_tkinter树形结构-CSDN博客详细给出了TinUI初版树状图的构建方法。TinUI原生treeview基本没有任何交互能力仅仅是数据结构的一种可视化展示。由于树状图的复杂性即便极尽简化为了使其具有基本交互能力也不适用于在TinUI标准内容中进行功能添加。因此一个更加高级的TinUI树状图控件在Smart-Space/TinUITreeview: TinUI高级树状图控件中单独提供。TinUITreeview为独立项目使用pip安装pip install tinuitreeview如上文所说树状图仍然是TinUI迄今为止最复杂的控件而且这个“上位替代”继承了原生树状图的主要构建方法因此本文基本上只讲怎么用。节点元素TinUITreeview内部使用节点元素来表示每个节点其类型classTinUITreeItem: 代表树中的一个节点持有画布对象 id 以及父/子关系。 属性只读由 TinUITreeView 维护 text - 节点显示文本 back - 背景矩形画布 id也是 items 字典的键 te - 文字画布 id sign - 展开/收起三角图标画布 id叶节点为 None parent - 父 TinUITreeItem根节点为 None children - 子 TinUITreeItem 列表 def__init__(self,text:str,back,te,signNone,parentNone):self.text:strtext self.backback# 背景self.tete# 文字self.signsign# 折叠图标叶节点为 Noneself.parent:TinUITreeItem|Noneparent self.children:list[TinUITreeItem][]注释里面也提到使用者几乎不需要关心这个类是什么但是其下成员属性仍可由使用者随时获取。高级树状图控件classTinUITreeView:_ICON_OPEN\ue96e_ICON_CLOSED\ue970def__init__(self,master:BasicTinUI,pos:tuple,fg#1a1a1a,bg#f3f3f3,onfg#1a1a1a,onbg#eaeaea,oncolor#3041d8,signcolor#8a8a8a,width200,height300,font微软雅黑 12,content((one,(1,2,3)),two,(three,(a,(b,(b1,b2,b3)),c)),four,),anchornw,commandNone,):#...其初始化参数与原生treeview一模一样基本可以无缝切换。需要注意的是command回调函数必须接受一个参数即选中项的路径确切来说就是一个TinUITreeItem列表从最高级节点到选中节点。获取当前选中元素get_selected(self)-TinUITreeItem|None通过调用该方法可获取当前选中的元素。添加节点add_node(self,text:str,parent:TinUITreeItem|NoneNone,)-TinUITreeItem当parent为None时即是向顶层末尾添加元素。如果parent存在且其本身是亲节点则添加在下级末尾否则会自动将其转为亲节点并赋予展开与折叠功能。会返回一个新建的元素。删除节点remove_node(self,item:TinUITreeItem)删除节点及其所有后代。若被删节点是亲节点的最后一个子节点则移除亲节点的折叠图标删除其展开与折叠功能。重命名节点rename_node(self,item:TinUITreeItem,new_text:str)给指定元素重命名。可以重名当然包括上级树状图内部靠元素id进行关系管理不过这是不必要的。折叠、展开所有defclose_all(self):foriteminlist(self._item_map.values()):ifitem.signandself._box.itemcget(item.sign,text)self._ICON_OPEN:self._close_view(item)defopen_all(self):foriteminlist(self._item_map.values()):ifitem.signandself._box.itemcget(item.sign,text)self._ICON_CLOSED:self._open_view(item)这部分同原生treeview。事件绑定defbind(self,sequenceNone,funcNone,addNone):绑定事件代理给画布实现returnself._box.bind(sequence,func,add)defunbind(self,sequence,funcidNone):解绑事件代理给画布实现self._box.unbind(sequence,funcid)面板布局使用TinUITreeView.uid获取控件uid用于TinUI面板布局。其行为与原生treeview一致。效果测试代码deftest(path):print(选中路径:, .join(n.textforninpath))roottk.Tk()tinuiBasicTinUI(root)tinui.pack(fillboth,expandTrue)treeTinUITreeView(tinui,(50,50),commandtest)# 增new_itemtree.add_node(新节点)# 添加到根childtree.add_node(子节点,parentnew_item)# 添加到指定节点下# 删# tree.remove_node(child) # 同时删除所有后代父节点若变为空则自动降级为叶节点# 改tree.rename_node(new_item,renamed)# 查# selected tree.get_selected() # 返回 TinUITreeItem 或 None# print(当前选中:, selected)# 展开/折叠tree.close_all()root.after(2000,tree.open_all)# 2秒后展开所有节点rpExpandPanel(tinui,tree.uid)defon_resize(e):rp.update_layout(5,5,e.width-5,e.height-5)tinui.bind(Configure,on_resize)root.mainloop()github项目TinUI的github项目地址pip下载pipinstalltinui