通过设置 setIndexWidget(QModelIndex, QWidget)
可以设置自定义 QWidget
- 对QListView设置代理
QSortFilterProxyModel
- 重写model的
lessThan
方法进行排序
需求:
- 5种分类(唐、宋、元、明、清) 和 未分类
- 选中唐则按照 唐、宋、元、明、清、未分类排序
- 选中宋则按照 宋、唐、元、明、清、未分类排序
- 选中元则按照 元、唐、宋、明、清、未分类排序
- 取消排序则恢复到加载时候顺序,如:未分类、唐、唐、明、清、未分类、宋、元、未分类
思路:
- 定义
IdRole = Qt.UserRole + 1
用于恢复默认排序 - 定义
ClassifyRole = Qt.UserRole + 2
用于按照分类序号排序 - 定义5种分类的id
NameDict = { '唐': ['Tang', 0], '宋': ['Song', 1], '元': ['Yuan', 2], '明': ['Ming', 3], '清': ['Qing', 4], } IndexDict = { 0: '唐', 1: '宋', 2: '元', 3: '明', 4: '清', }
- item设置
setData(id, IdRole)
用于恢复默认排序 - item设置
setData(cid, ClassifyRole)
用于标识该item的分类 - 继承
QSortFilterProxyModel
增加setSortIndex(self, index)
方法, 目的在于记录要置顶(不参与排序)的分类IDdef setSortIndex(self, index): self._topIndex = index
- 继承
QSortFilterProxyModel
重写lessThan
方法, 判断分类ID是否等于要置顶的ID, 如果是则修改为-1, 这样就永远在最前面if self.sortRole() == ClassifyRole and \ source_left.column() == self.sortColumn() and \ source_right.column() == self.sortColumn(): # 获取左右两个的分类 leftIndex = source_left.data(ClassifyRole) rightIndex = source_right.data(ClassifyRole) # 升序 if self.sortOrder() == Qt.AscendingOrder: # 保持在最前面 if leftIndex == self._topIndex: leftIndex = -1 if rightIndex == self._topIndex: rightIndex = -1 return leftIndex < rightIndex
- 恢复默认排序
self.fmodel.setSortRole(IdRole) # 必须设置排序角色为ID self.fmodel.sort(0) # 排序第一列按照ID升序
- 根据分类排序, 这里要注意要先通过
setSortRole
设置其它角色再设置目标角色self.fmodel.setSortIndex(1) self.fmodel.setSortRole(IdRole) self.fmodel.setSortRole(ClassifyRole) self.fmodel.sort(0)