PyQt/QListView/README.md
2019-05-22 11:07:42 +08:00

3.2 KiB
Raw Blame History

QListView

1、显示自定义Widget

运行 CustomWidgetItem.py

通过设置 setIndexWidget(QModelIndex, QWidget) 可以设置自定义 QWidget

CustomWidgetItem

2、显示自定义Widget并排序

运行 CustomWidgetSortItem.py

  1. 对QListView设置代理 QSortFilterProxyModel
  2. 重写model的 lessThan 方法进行排序

CustomWidgetSortItem

3、自定义角色排序

运行 SortItemByRole.py

需求:

  1. 5种分类唐、宋、元、明、清 和 未分类
  2. 选中唐则按照 唐、宋、元、明、清、未分类排序
  3. 选中宋则按照 宋、唐、元、明、清、未分类排序
  4. 选中元则按照 元、唐、宋、明、清、未分类排序
  5. 取消排序则恢复到加载时候顺序,如:未分类、唐、唐、明、清、未分类、宋、元、未分类

思路:

  1. 定义IdRole = Qt.UserRole + 1 用于恢复默认排序
  2. 定义ClassifyRole = Qt.UserRole + 2 用于按照分类序号排序
  3. 定义5种分类的id
    NameDict = {
        '唐': ['Tang', 0],
        '宋': ['Song', 1],
        '元': ['Yuan', 2],
        '明': ['Ming', 3],
        '清': ['Qing', 4],
    }
    IndexDict = {
        0: '唐',
        1: '宋',
        2: '元',
        3: '明',
        4: '清',
    }
    
  4. item设置 setData(id, IdRole) 用于恢复默认排序
  5. item设置 setData(cid, ClassifyRole) 用于标识该item的分类
  6. 继承 QSortFilterProxyModel 增加 setSortIndex(self, index) 方法, 目的在于记录要置顶不参与排序的分类ID
    def setSortIndex(self, index):
        self._topIndex = index
    
  7. 继承 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
    
  8. 恢复默认排序
    self.fmodel.setSortRole(IdRole)     # 必须设置排序角色为ID
    self.fmodel.sort(0)                 # 排序第一列按照ID升序
    
  9. 根据分类排序, 这里要注意要先通过 setSortRole 设置其它角色再设置目标角色
    self.fmodel.setSortIndex(1)
    self.fmodel.setSortRole(IdRole)
    self.fmodel.setSortRole(ClassifyRole)
    self.fmodel.sort(0)
    

SortItemByRole