2024年最全《tkinter实用教程21》treeview 节点插入、单选、多选、事件(1),大厂面试官

结尾

学习html5、css、javascript这些基础知识,学习的渠道很多,就不多说了,例如,一些其他的优秀博客。但是本人觉得看书也很必要,可以节省很多时间,常见的javascript的书,例如:javascript的高级程序设计,是每位前端工程师必不可少的一本书,边看边用,了解js的一些基本知识,基本上很全面了,如果有时间可以读一些,js性能相关的书籍,以及设计者模式,在实践中都会用的到。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

高级程序设计,是每位前端工程师必不可少的一本书,边看边用,了解js的一些基本知识,基本上很全面了,如果有时间可以读一些,js性能相关的书籍,以及设计者模式,在实践中都会用的到。

html5

  • Treeview 参数解读

  • 作为表格使用 Treeview

  • 作为树使用 Treeview

  • Treeview 插入子节点

  • Treeview 事件

  • 如何获取当前选中项

  • 单选项获取

  • 多选项获取

  • Tree 选中子节点

更多《Tkinter 实用教程》系列文章

tkinter Treeview 控件的使用方法


创建 Treeview 控件

创建 Treeview 使用 ttk.Treeview 类,语法如下:

tree = ttk.Treeview(master, options)

Treeview 参数解读

| 参数 | 作用 |

| — | — |

| columns | 接收一个列表(tuple),列表中的每个元素都代表表格中的一列(可以理解为 ID),列表的长度就是表格的列数。 |

| displaycolumns | 接收一个列表(tuple),列表每个元素都代表 columns 中列的编号,用于设置列表要显示的列,以及显示列的顺序(没有在列表中的列不会显示)。传入"#all"显示所有列。 |

| height | 表格的高度,也就是能够显示的行数。 |

| padding | 内容距离组件边缘的距离。 |

| selectmode | 有 "extended"(默认选项)、"browse""none"三种选项,分别代表多选(Ctrl+鼠标左键),单选以及不能改变选项。 |

| show | 有 "tree""headings""tree headings" 三种选项,分别代表显示图标列(编号为 "#0")、不显示图标列(仅显示数值列)以及显示所有列(图标列和数值列)。 个人理解:用作树需要加上"tree",用作表使用"headings"。 |

作为表格使用 Treeview

以下代码展示了将 Treeview 控件作为表格使用,展示一系列数据的方法:

from tkinter import *

from tkinter import ttk

“”"

魏大王学编程(www.weidawang.xyz)

tkinter 实用教程系列

Treeview 作为表格使用的简单案例

“”"

main = Tk()

data = [(1, “小明”, 23, ‘男’, ‘2021-09-21’), (2, “小强”, 23, ‘男’, ‘2021-09-21’),

(3, “小红”, 23, ‘女’, ‘2021-09-21’), (4, “铁头”, 23, ‘男’, ‘2021-09-21’)]

tree = ttk.Treeview(main, columns=(‘id’, ‘name’, ‘age’, ‘sex’, ‘birth’), show=“headings”, displaycolumns=“#all”)

tree.heading(‘id’, text=“编号”, anchor=W)

tree.heading(‘name’, text=“姓名”, anchor=W)

tree.heading(‘age’, text=“年龄”, anchor=W)

tree.heading(‘sex’,text=“性别”,anchor=W)

tree.heading(‘birth’, text=“出生日期”, anchor=W)

for itm in data:

tree.insert(“”,END,values=itm)

tree.pack(expand=1, fill=BOTH)

main.mainloop()

代码执行结果如下图所示:

01_create.png

作为树使用 Treeview

from tkinter import *

from tkinter import ttk

“”"

魏大王学编程(www.weidawang.xyz)

tkinter 实用教程系列

Treeview 作为树使用的简单案例

“”"

main = Tk()

data = [(1, “小明”, 23, ‘男’, ‘2021-09-21’), (2, “小强”, 23, ‘男’, ‘2021-09-21’),

(3, “小红”, 23, ‘女’, ‘2021-09-21’), (4, “铁头”, 23, ‘男’, ‘2021-09-21’)]

tree = ttk.Treeview(main, columns=(‘id’, ‘name’, ‘age’, ‘sex’,‘birth’), show=“tree headings”, displaycolumns=“#all”)

tree.heading(“#0”, text=“学校”, anchor=W)

tree.heading(‘id’, text=“编号”, anchor=W)

tree.heading(‘name’, text=“姓名”, anchor=W)

tree.heading(‘age’, text=“年龄”, anchor=W)

tree.heading(‘sex’, text=“性别”, anchor=W)

tree.heading(‘birth’, text=“出生日期”, anchor=W)

stu_root = tree.insert(“”, END, text=“学生”)

man = tree.insert(stu_root, END, text=“男”)

wom = tree.insert(stu_root, END, text=“女”)

for itm in data:

if(itm[3]==“男”):

tree.insert(man,END,text=itm[1],values=itm)

else:

tree.insert(wom,END,text=itm[1],values=itm)

tree.pack(expand=1, fill=BOTH)

main.mainloop()

代码执行结果:

02_as_tree.png

如果将代码中 displaycolumns="#all" 修改为 displaycolums=() ,树的效果如下:

03_as_tree2.png

Treeview 插入子节点

向 Treeview 对象中插入一个子节点,需要使用 insert 方法:

itm = tree.insert(options)

insert 函数的返回值,就是插入节点的对象。

参数列表如下:

| 参数 | 描述 |

| — | — |

| parent | 指定父节点,如果需要插入根节点,传入""。 |

| index | 指定插入位置,0表示在头部插入,END表示在尾部插入。 |

| text | 指定在图标栏展示的内容,也就是在编号"#0"列展示的内容,只有 show 参数包含 tree 时才能看到。 |

| values | 指定在数据列展示的内容,也就是 columns 指定的列。 |

| image | 指定图标栏显示的图标,是一个PhotoImage对象 |

Treeview 事件

Treeview 有三个虚拟事件分别是:

  • <<TreeviewSelect>>:选中项发生变化时触发该事件;

  • <<TreeviewOpen>>:当菜单项open=True时触发该事件;

  • <<TreeviewClose>>:当菜单项open=False时触发该事件;

这些事件的使用方法和之前的控件一样,比较简单,下文有案例,不过多解释。

如何获取当前选中项

获取当前选中项有两种情况,第一种就是单选项的获取,比较简单,而多选项的获取稍微复杂了一点。

单选项获取

先使用 Treeview 的 focus() 方法获取当前焦点项,再利用 set 方法获取焦点项的值。

获取到的值就是在插入表、树子节点时时指定的 values 值。

foc = tree.focus()

val = tree.set(foc)

示例代码如下:

from tkinter import *

from tkinter import ttk

“”"

魏大王学编程(www.weidawang.xyz)

tkinter 实用教程系列

Treeview 事件案例

“”"

def onSelect(e):

itm = tree.set(tree.focus())

print(itm)

pass

main = Tk()

data = [(1, “小明”, 23, ‘男’, ‘2021-09-21’), (2, “小强”, 23, ‘男’, ‘2021-09-21’),

(3, “小红”, 23, ‘女’, ‘2021-09-21’), (4, “铁头”, 23, ‘男’, ‘2021-09-21’)]

tree = ttk.Treeview(main, columns=(‘id’, ‘name’, ‘age’, ‘sex’,

‘birth’), show=“headings”, displaycolumns=“#all”)

tree.heading(‘id’, text=“编号”, anchor=W)

tree.heading(‘name’, text=“姓名”, anchor=W)

tree.heading(‘age’, text=“年龄”, anchor=W)

tree.heading(‘sex’,text=“性别”,anchor=W)

tree.heading(‘birth’, text=“出生日期”, anchor=W)

for itm in data:

tree.insert(“”,END,values=itm)

tree.pack(expand=1, fill=BOTH)

tree.bind(“<>”,onSelect)

main.mainloop()

04_get_select.png

专业技能

一般来说,面试官会根据你的简历内容去提问,但是技术基础还有需要自己去准备分类,形成自己的知识体系的。简单列一下我自己遇到的一些题

最近得空把之前遇到的面试题做了一个整理,包括我本人自己去面试遇到的,还有其他人员去面试遇到的,还有网上刷到的,我都统一的整理了一下,希望对大家有用。

其中包含HTML、CSS、JavaScript、服务端与网络、Vue、浏览器等等

由于文章篇幅有限,仅展示部分内容

<think>我们正在讨论如何为TreeView控件添加功能。根据引用[1][2][3],我们可以总结出以下关键点: 1. 需要启用模式(通常通过设置属性实现)。 2. 需要处理用户交互事件(鼠标点击、键盘辅助键)。 3. 需要编写逻辑代码来管理节点中状态。 具体步骤: 1. 设置TreeView控件支持:在C#中,可以通过设置`CheckBoxes`属性为`true`来实现每个节点前的复框,但这并不是真正的(通常用于单选或通过复)。而真正的(类似文件资源管理器那样用Shift和Ctrl)需要设置`HideSelection`为`false`,并处理键盘和鼠标事件。 2. 处理事件:主要需要处理`MouseDown`、`MouseUp`、`KeyDown`(特别是Ctrl和Shift)等事件。 3. 管理节点:在事件处理函数中,根据当前按下的键(Ctrl或Shift)和点击的节点,更新节点集合。 在C#中,我们可以通过以下方式实现: - 使用`TreeView`的`BeforeSelect`和`AfterSelect`事件,或者重写`OnMouseDown`等方法。 - 维护一个中的节点列表(`List<TreeNode>`)。 然而,TreeView控件默认不支持,因此我们需要自定义一个从TreeView继承的控件,并添加功能。 以下是一个简单的实现思路: ```csharp public class MultiSelectTreeView : TreeView { // 存储中的节点 private List<TreeNode> selectedNodes = new List<TreeNode>(); // 是否正在通过代码改变中状态(避免事件重入) private bool selecting = false; public MultiSelectTreeView() { // 设置样式,允许在节点上绘制择矩形 this.DrawMode = TreeViewDrawMode.OwnerDrawText; this.HideSelection = false; // 即使失去焦点也保持中状态可见 } // 公开中的节点集合(只读) public List<TreeNode> SelectedNodes { get { return selectedNodes; } } protected override void OnDrawNode(DrawTreeNodeEventArgs e) { // 自定义绘制节点,以突出显示中的节点 if (selectedNodes.Contains(e.Node)) { // 绘制中背景 e.Graphics.FillRectangle(SystemBrushes.Highlight, e.Bounds); TextRenderer.DrawText(e.Graphics, e.Node.Text, this.Font, e.Bounds, SystemColors.HighlightText); } else { e.DrawDefault = true; } } protected override void OnMouseDown(MouseEventArgs e) { // 获取点击的节点 TreeNode clickedNode = this.GetNodeAt(e.Location); if (clickedNode == null) return; // 如果按下了Ctrl键,则进行 if (Control.ModifierKeys == Keys.Control) { if (selectedNodes.Contains(clickedNode)) { selectedNodes.Remove(clickedNode); } else { selectedNodes.Add(clickedNode); } } // 如果按下了Shift键,则进行范围择 else if (Control.ModifierKeys == Keys.Shift) { // 找到上一个中的节点(作为起始节点) if (selectedNodes.Count > 0) { TreeNode startNode = selectedNodes[selectedNodes.Count - 1]; // 获取从startNode到clickedNode之间的所有节点 // 注意:这里需要根据树的结构实现,可能比较复杂,因为树可能有折叠的节点 // 这里简化处理:只择同一层级连续的节点(实际应用中可能需要递归遍历) // 具体实现略,需要根据实际需求编写 } } else { // 没有按下辅助键,则清空节点,只中当前节点 selectedNodes.Clear(); selectedNodes.Add(clickedNode); } // 触发重绘 this.Invalidate(); base.OnMouseDown(e); } // 其他事件处理,如键盘事件(处理空格键、方向键等) } ``` 注意:上述代码只是一个简化的示例,实际应用中需要处理更细节,比如: - 如何跨层级节点? - 如何绘制中状态(使用DrawMode为OwnerDrawText时,需要自己绘制背景和文本)? - 如何支持通过键盘(空格键)节点? 另外,引用[3]中提到了tkinterTreeview控件,它是Python的GUI库,其实现方式与C#不同。在tkinter中,Treeview控件可以通过设置`selectmode`为`extended`(默认就是模式)来支持。但我们的问题是在C#中,所以主要参考C#的实现。 在C#中,更常见的做法是使用第三方控件,或者通过上述自定义控件的方式实现。 总结步骤: 1. 创建一个继承自TreeView的自定义控件。 2. 添加一个集合来存储中的节点。 3. 重写鼠标事件和键盘事件,根据用户操作更新节点集合。 4. 重绘节点,以显示中状态。 §§相关问题§§ 1. 在C#中,如何为TreeView控件添加复框(CheckBoxes)并实现? 2. TreeView控件时,如何实现跨层级节点? 3. 在自定义TreeView控件中,如何支持拖拽中的节点?</think>### TreeView控件实现节点功能 在C#的Windows窗体应用中,TreeView控件默认不支持操作。根据引用[1][2][3],实现功能需要以下关键步骤: #### 1. 启用模式 ```csharp // 设置TreeView属性 treeView1.HideSelection = false; // 失去焦点时保持中状态可见 treeView1.CheckBoxes = false; // 不依赖复框(可) ``` #### 2. 事件处理逻辑 ```csharp // 鼠标点击事件 private void treeView1_MouseDown(object sender, MouseEventArgs e) { TreeNode clickedNode = treeView1.GetNodeAt(e.Location); if (clickedNode == null) return; // Ctrl键:添加/移除中 if ((Control.ModifierKeys & Keys.Control) == Keys.Control) { clickedNode.BackColor = clickedNode.BackColor == Color.LightBlue ? Color.White : Color.LightBlue; } // Shift键:范围择 else if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) { SelectRange(clickedNode); } // 单选模式 else { ClearSelection(); clickedNode.BackColor = Color.LightBlue; } } // 键盘事件支持 protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { if (keyData == (Keys.Control | Keys.A)) // Ctrl+A全 { SelectAllNodes(); return true; } return base.ProcessCmdKey(ref msg, keyData); } ``` #### 3. 核心功能实现 ```csharp // 清除所有中状态 private void ClearSelection() { foreach (TreeNode node in treeView1.Nodes) { node.BackColor = Color.White; ClearChildSelection(node); } } // 递归清除子节点 private void ClearChildSelection(TreeNode parent) { foreach (TreeNode child in parent.Nodes) { child.BackColor = Color.White; ClearChildSelection(child); } } // 范围择(简化示例) private void SelectRange(TreeNode endNode) { TreeNode startNode = // 获取上次中的节点(需维护状态) // 遍历树结构找到两者之间的所有节点 // 设置这些节点的BackColor = Color.LightBlue } // 获取所有节点 public List<TreeNode> GetSelectedNodes() { var selected = new List<TreeNode>(); foreach (TreeNode node in treeView1.Nodes) { if (node.BackColor == Color.LightBlue) selected.Add(node); FindSelectedChildNodes(node, selected); } return selected; } private void FindSelectedChildNodes(TreeNode parent, List<TreeNode> selected) { foreach (TreeNode child in parent.Nodes) { if (child.BackColor == Color.LightBlue) selected.Add(child); FindSelectedChildNodes(child, selected); } } ``` #### 4. 使用注意事项 1. **性能优化**:对于大型树结构,建议使用`Tag`属性存储中状态而非直接修改`BackColor` 2. **可视化反馈**:通过改变节点背景色提供视觉反馈(也可使用图像或字体样式) 3. **状态管理**:维护一个`List<TreeNode>`存储当前节点集合 4. **键盘支持**:需处理`KeyDown`事件响应方向键导航[^1] > 实现要点:通过修改节点视觉属性(如背景色)表示中状态,结合Ctrl/Shift键处理逻辑。实际应用中需考虑跨层级择、折叠节点处理等复杂场景[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值