当前位置:   article > 正文

python tkinter treeview 表格全选、鼠标拖拽选中表格_tkinter 勾选 表格

tkinter 勾选 表格

在网上有很多tkinter相关的教学,也有很多treeview相关方法的介绍,但是treeview表格选中相关的介绍比较少,这里分享一下个人使用过程中的经验。

与选中相关有两个函数,一个是selection,一个是selection_set。

可以用selection函数获取集合,包含了所有选中的单元的iid。

treeview中,选中单位可以用selection_set函数设定,这个函数的对象是treeview类,方法的参数是目标的iid。如果传入参数是一个iid,只选择一个目标,如果传入列表等,就会选中多行目标。

全选表格

我们可以遍历整个表格,把每一行的iid保存到一个列表中,然后将列表传递给selection_set函数,就可以选中整个表格。

  1. import tkinter as tk
  2. from tkinter import ttk
  3. def select_all_items(tree):
  4. select = []
  5. for item in tree.get_children():
  6. select.append(item)
  7. tree.selection_set(select)
  8. print(tree.selection()) #打印查看选中行的iid
  9. root = tk.Tk()
  10. tree = ttk.Treeview(root)
  11. tree.pack(fill=tk.BOTH, expand=True)
  12. # 假设你已经填充了treeview,下面是添加条目的示例代码
  13. for i in range(5):
  14. tree.insert('', 'end', text=f"Item {i}")
  15. # 全选按钮
  16. select_all_button = ttk.Button(root, text="Select All", command=lambda: select_all_items(tree))
  17. select_all_button.pack()
  18. root.mainloop()

这段代码基于百度ai,但是ai直接生成的代码有问题。他每次传入一个位置,运行的时候速度太快,人是看不见的,最后结果是选中了最后一个选项。

鼠标拖拽选中

绑定事件

鼠标拖拽主要有三个动作,按下鼠标、移动、松开,我们可以用三个函数处理对应的操作并绑定到事件。

  1. # 绑定事件
  2. tree.bind("<ButtonPress-1>", self.on_mouse_click)
  3. tree.bind("<ButtonRelease-1>", self.on_mouse_release)
  4. tree.bind("<B1-Motion>", self.on_mouse_motion)

选中区域管理

我们在选中区域的时候,会有一个起点位置,这个位置无论如何最终都会被选中。当我们把鼠标远离起点位置时,会加入更多的行,反过来靠近时则会去掉多余的行。在行的进出过程中,其顺序符合先入后出的原则,所以我们用一个类似队列的结构去管理我们要选中的区域。

按下鼠标

按下鼠标后进入事件处理函数,首先判断事件是否和我们的表格相关。将鼠标位置的行作为第一个元素加入队列中,然后用一个布尔类记录启动信号,表示已经开始拖拽。

  1. # 如果是按下左键,开始拖拽选择
  2. tree = self.tree
  3. if event.widget == tree:
  4. self.selection_trace = [tree.identify_row(event.y)]
  5. tree.selection_set(tree.identify_row(event.y))
  6. self.drag_start.set(True)

 移动鼠标

每次移动鼠标,我们首先获取当前所在行的iid。当我们移动到新的一行,就把新的一行加入到队列,如果回到上一行,就把队尾的元素踢出。这样的话,我们的队列中,队尾是上一次加入的新元素,队尾的前一个是上次加入的元素(如果有的话)。

如果鼠标在同一行移动,每次获取的都是同一行,应当与队尾为同一行,因此要判断是否在同一行移动。如果在同一行,就不做任何处理。

  1. if next_row == self.selection_trace[-1]: #原来行没变
  2. return

 假设起点在上方,鼠标往下移动移动到新的行,往上移动到原来行位置。原来行对应队列中倒数第二个元素,新的行在队列中没有元素,需要比较当前行的位置判断移动方向。由于最开始的时候队列中只有一个元素,使用下标访问[-2]会越界,因此先判断队列的长度。

  1. if len(self.selection_trace) == 1 or next_row != self.selection_trace[-2]:
  2. self.selection_trace.append(next_row)

 如果队列中倒数第二个元素与当前行相同,说明鼠标往上走也就是回去了,这时候就抛出队尾。

tree.selection_set(self.selection_trace)

 这部分代码合起来

  1. # 如果已经开始拖拽,更新选择区域
  2. tree = self.tree
  3. if event.widget == tree and self.drag_start.get():
  4. next_row = tree.identify_row(event.y)
  5. if next_row == self.selection_trace[-1]: #原来行没变
  6. return
  7. if len(self.selection_trace) == 1 or next_row != self.selection_trace[-2]:
  8. self.selection_trace.append(next_row)
  9. else: #回去一行
  10. self.selection_trace.pop(-1)
  11. tree.selection_set(self.selection_trace)

 松开鼠标

将开始的标志赋值为否,表示拖拽选中已经停止。

  1. def on_mouse_release(self, event):
  2. # 如果是释放左键,结束拖拽选择
  3. tree = self.tree
  4. if event.widget == tree and self.drag_start.get():
  5. self.drag_start.set(False)
'
运行

 完整的代码如下,额外添加了右键选中。

  1. import tkinter as tk
  2. from tkinter import ttk
  3. class drag_select_tree:
  4. def __init__(self, root):
  5. self.root = root
  6. self.drag_start = tk.BooleanVar() # 开始拖拽选择的标志
  7. self.drag_start.set(False)
  8. self.create_tree()
  9. def create_tree(self):
  10. tree = ttk.Treeview(root, columns=("Size", "Modified"), selectmode='extended')
  11. tree.pack(fill="both", expand=True)
  12. self.tree = tree
  13. # 创建示例数据
  14. for i in range(10):
  15. tree.insert("", "end", text=f"Item {i}", values=(f"Size {i}", f"Modified {i}"))
  16. # 绑定事件
  17. tree.bind("<ButtonPress-1>", self.on_mouse_click)
  18. tree.bind("<ButtonPress-3>", self.on_mouse_click)
  19. tree.bind("<ButtonRelease-1>", self.on_mouse_release)
  20. tree.bind("<ButtonRelease-3>", self.on_mouse_release)
  21. tree.bind("<B1-Motion>", self.on_mouse_motion)
  22. tree.bind("<B3-Motion>", self.on_mouse_motion)
  23. def on_mouse_click(self, event):
  24. # 如果是按下左键,开始拖拽选择
  25. tree = self.tree
  26. if event.widget == tree:
  27. self.selection_trace = [tree.identify_row(event.y)]
  28. tree.selection_set(tree.identify_row(event.y))
  29. self.drag_start.set(True)
  30. def on_mouse_release(self, event):
  31. # 如果是释放左键,结束拖拽选择
  32. tree = self.tree
  33. if event.widget == tree and self.drag_start.get():
  34. self.drag_start.set(False)
  35. def on_mouse_motion(self, event):
  36. # 如果已经开始拖拽,更新选择区域
  37. tree = self.tree
  38. if event.widget == tree and self.drag_start.get():
  39. next_row = tree.identify_row(event.y)
  40. if next_row == self.selection_trace[-1]: #原来行没变
  41. return
  42. if len(self.selection_trace) == 1 or next_row != self.selection_trace[-2]:
  43. self.selection_trace.append(next_row)
  44. else: #回去一行
  45. self.selection_trace.pop(-1)
  46. tree.selection_set(self.selection_trace)
  47. root = tk.Tk()
  48. drag_select_tree(root)
  49. root.mainloop()

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/975509
推荐阅读
相关标签
  

闽ICP备14008679号