Add sorting capability for "选择" and "材料名称" columns in the CheckboxTreeview: - Click column header to cycle through: asc (↑) → desc (↓) → unsort - Sort "选择" column by checkbox state (checked/unchecked) - Sort "材料名称" column alphabetically - Preserve checkbox states during sorting using move() instead of delete+insert - Separate event handlers for cell clicks and heading clicks Implementation details: - Added 6 new helper methods to CheckboxTreeview class - Store original headings to properly display sort arrows - Use identify_region() to distinguish between cell and heading clicks - Column index conversion (#1/#2) to column identifiers The sorting is a pure frontend feature with no database changes. Available to all users without permission restrictions. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
5.7 KiB
5.7 KiB
CheckboxTreeview 排序功能实施总结
实施日期
2026-02-24
功能概述
为物料校验界面的校验结果表格添加了排序功能,支持对"选择"和"材料名称"列进行升序、降序排序,并可取消排序。
修改文件
D:\python\playwrite\gui\material_validation_tab.py
修改内容
1. CheckboxTreeview.init 方法(第35-60行)
新增变量:
# 排序状态
self.sort_column = None # 当前排序列的列标识符
self.sort_direction = None # 'asc', 'desc', 或 None
self.sortable_columns = ["选择", "材料名称"] # 可排序的列白名单
self.original_headings = {} # 存储原始列标题文本(不含箭头)
# 存储原始列标题(延迟执行以确保标题已设置)
self.after(100, self._store_original_headings)
# 绑定表头点击事件
self.bind("<ButtonRelease-1>", self._on_heading_click)
2. CheckboxTreeview._on_click 方法(第62-83行)
修改内容:
- 添加注释说明仅处理单元格点击,不处理表头点击
- 确保与表头点击事件分离,避免冲突
3. 新增方法
_store_original_headings(第142-145行)
存储原始列标题文本,避免排序箭头影响后续操作。
_get_column_id_from_column_index(第147-160行)
将列索引('#1', '#2')转换为列标识符('选择', '材料名称')。
_on_heading_click(第162-172行)
处理表头点击事件,触发排序操作。仅对可排序列("选择"、"材料名称")生效。
_toggle_sort(第174-204行)
切换排序状态的核心方法:
- 同一列:asc → desc → None(循环)
- 不同列:重置为升序
- 调用排序方法并更新表头显示
_sort_by_column(第206-237行)
执行实际排序操作:
- 收集所有项目的数据和复选框状态
- 根据列类型使用不同的排序逻辑
- 使用
move()方法保留项目ID和复选框状态
排序逻辑:
- "选择"列: 按复选框状态排序(False 未选中在前 → True 选中在前)
- "材料名称"列: 按字符串字母顺序排序
_update_heading_display(第239-248行)
更新列标题显示:
- 排序列:显示原始标题 + 箭头(↑ 升序,↓ 降序)
- 非排序列:显示原始标题
排序行为
"选择"列
- 升序 (↑): 未选中 (☐) → 选中 (☑)
- 降序 (↓): 选中 (☑) → 未选中 (☐)
"材料名称"列
- 升序 (↑): A → Z 字母顺序
- 降序 (↓): Z → A 字母顺序
点击循环
- 第一次点击: 升序(显示 ↑)
- 第二次点击: 降序(显示 ↓)
- 第三次点击: 取消排序(移除箭头)
技术要点
1. 使用 move() 而非 delete() + insert()
delete()会删除项目及其关联的复选框状态move()仅改变项目位置,保留项目ID- 项目ID与
self.checkboxes字典中的复选框状态关联 - 使用
move()可自动保持复选框状态
2. 事件绑定策略
<Button-1>: 现有复选框点击事件(在_on_click中处理)<ButtonRelease-1>: 新增的表头点击事件(在_on_heading_click中处理)- 使用
identify_region区分点击区域("cell" vs "heading")
3. 延迟存储原始标题
self.after(100, self._store_original_headings)
确保在 Treeview 标题设置完成后再存储,避免获取空值。
4. 复选框状态保持
排序过程中:
- 收集所有项目的
item_id和checkbox_state - 对数据列表进行排序
- 使用
move()重新排列项目 self.checkboxes字典自动保持正确状态(key 是 item_id)
兼容性
向后兼容
- ✅ 所有现有功能保持不变
- ✅ 复选框点击功能正常
- ✅ 全选/取消全选功能正常
- ✅ 复选框状态同步功能正常
- ✅ 双击编辑负责人功能正常
无权限限制
- ✅ 适用于所有用户(管理员和普通用户)
- ✅ 无需修改权限控制代码
测试建议
功能测试
-
"选择"列排序:
- 点击列头 → 未选中项目排到最前面
- 再次点击 → 选中项目排到最前面
- 第三次点击 → 箭头消失
-
"材料名称"列排序:
- 点击列头 → 按字母 A-Z 升序排列
- 再次点击 → 按字母 Z-A 降序排列
- 第三次点击 → 箭头消失
-
复选框状态保持:
- 选中几个项目
- 进行排序
- 验证复选框状态保持不变
-
跨列切换:
- 在"选择"列排序后,点击"材料名称"列
- 验证"选择"列箭头消失,"材料名称"列显示箭头
- 验证按新的列排序
-
复选框点击兼容性:
- 排序后点击复选框
- 验证复选框状态切换功能正常
边界情况测试
- 空表格: 排序不应报错
- 单行数据: 排序不应报错
- 所有项目相同值: 排序不应改变顺序
- 中文字符排序: 验证中文排序正确
- 动态添加数据: 排序后添加新数据,验证排序状态保持
风险评估
- 低风险: 仅影响 CheckboxTreeview 的显示和交互
- 向后兼容: 所有现有功能保持不变
- 无数据库改动: 纯前端排序功能
- 可测试性: 容易手动测试验证
预期效果
用户可以通过点击"选择"或"材料名称"列头,快速对数据进行排序,提高数据查看和分析效率。排序状态通过箭头直观显示,符合常见 UI 交互习惯。
测试文件
已创建测试脚本:tests/test_sorting.py
运行测试:
python tests/test_sorting.py
后续优化建议
- 可扩展到其他列的排序(如"负责人"、"材料代码"等)
- 可添加多列排序功能(按住 Shift 点击第二列)
- 可添加排序持久化(记住用户的排序偏好)