diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs index bb8938b..78beb7e 100644 --- a/.settings/org.eclipse.core.resources.prefs +++ b/.settings/org.eclipse.core.resources.prefs @@ -1,5 +1,7 @@ eclipse.preferences.version=1 encoding//QAxWidget/\u663E\u793Aword_excel_pdf.py=utf-8 +encoding//QListView/CustomWidgetSortItem.py=utf-8 +encoding//QListView/SortItemByRole.py=utf-8 encoding//QProxyStyle/Lib/TabBarStyle.py=utf-8 encoding//QProxyStyle/TabTextDirection.py=utf-8 encoding//QTableView/CopyContent/CopyContent.py=utf-8 diff --git a/QListView/ScreenShot/SortItemByRole.gif b/QListView/ScreenShot/SortItemByRole.gif new file mode 100644 index 0000000..9015cf6 Binary files /dev/null and b/QListView/ScreenShot/SortItemByRole.gif differ diff --git a/QListView/SortItemByRole.py b/QListView/SortItemByRole.py new file mode 100644 index 0000000..74bb241 --- /dev/null +++ b/QListView/SortItemByRole.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Created on 2018年12月27日 +@author: Irony +@site: https://pyqt5.com https://github.com/892768447 +@email: 892768447@qq.com +@file: QListView.SortItemByRole +@description: +""" +from random import choice + +from PyQt5.QtCore import QSortFilterProxyModel, Qt, QTimer +from PyQt5.QtGui import QStandardItem, QStandardItemModel +from PyQt5.QtWidgets import QWidget, QVBoxLayout, QListView, QPushButton + + +__Author__ = """By: Irony +QQ: 892768447 +Email: 892768447@qq.com""" +__Copyright__ = "Copyright (c) 2018 Irony" +__Version__ = "Version 1.0" + + +class SortFilterProxyModel(QSortFilterProxyModel): + + def __init__(self, *args, **kwargs): + super(SortFilterProxyModel, self).__init__(*args, **kwargs) + self._topIndex = 0 + + def setSortIndex(self, index): + self._topIndex = index + print('在最前面的序号为:', index) + + def lessThan(self, source_left, source_right): + if not source_left.isValid() or not source_right.isValid(): + return False + + 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 + elif rightIndex == self._topIndex: + rightIndex = -1 + + return leftIndex < rightIndex + + return super(SortFilterProxyModel, self).lessThan(source_left, source_right) + + +NameDict = { + '唐': ['Tang', 0], + '宋': ['Song', 1], + '元': ['Yuan', 2], + '明': ['Ming', 3], + '清': ['Qing', 4], +} +IndexDict = { + 0: '唐', + 1: '宋', + 2: '元', + 3: '明', + 4: '清', +} +BigIndex = 100 + +IdRole = Qt.UserRole + 1 # 用于恢复排序 +ClassifyRole = Qt.UserRole + 2 # 用于按照分类序号排序 + + +class Window(QWidget): + + def __init__(self, *args, **kwargs): + super(Window, self).__init__(*args, **kwargs) + self.resize(600, 400) + layout = QVBoxLayout(self) + self.listView = QListView(self) + self.listView.setEditTriggers(QListView.NoEditTriggers) + layout.addWidget(self.listView) + layout.addWidget(QPushButton('恢复默认顺序', self, clicked=self.restoreSort)) + layout.addWidget(QPushButton('唐', self, clicked=self.sortByClassify)) + layout.addWidget(QPushButton('宋', self, clicked=self.sortByClassify)) + layout.addWidget(QPushButton('元', self, clicked=self.sortByClassify)) + layout.addWidget(QPushButton('明', self, clicked=self.sortByClassify)) + layout.addWidget(QPushButton('清', self, clicked=self.sortByClassify)) + + self._initItems() + + def restoreSort(self): + # 恢复默认排序 + self.fmodel.setSortRole(IdRole) # 必须设置排序角色为ID + self.fmodel.sort(0) # 排序第一列按照ID升序 + + def sortByClassify(self): + self.fmodel.setSortIndex(NameDict.get( + self.sender().text(), ['', BigIndex])[1]) + self.restoreSort() + # 按照给定的分类排序(这里注意还要按照把给定分类的放在最前面) + self.fmodel.setSortRole(ClassifyRole) + QTimer.singleShot(100, lambda: self.fmodel.sort(0)) + + def _initItems(self): + # 初始化Items + self.dmodel = QStandardItemModel(self.listView) + self.fmodel = SortFilterProxyModel(self.listView) + self.fmodel.setSourceModel(self.dmodel) + self.listView.setModel(self.fmodel) + + keys = list(NameDict.keys()) + print(keys) # ['清', '元', '唐', '明', '宋'] + classifies = [v[1] for v in NameDict.values()] + for i in range(5): + # 添加5个100, 用于模拟没有分类, 排序的时候就显示在最后面 + classifies.append(BigIndex) + print(classifies) # [4, 2, 0, 3, 1, 100, 100, 100, 100, 100] + + # 生成50个Item + for i in range(50): + # name = keys[i % 4] # 随机取一个朝代 + item = QStandardItem() + # 设置ID角色 + item.setData(i, IdRole) + # 设置分类角色 + c = choice(classifies) + item.setData(c, ClassifyRole) + # 设置显示内容 + item.setText('Name: {}\t\tId: {}\t\tClassify: {}'.format( + IndexDict.get(c, '其它'), i, c)) + self.dmodel.appendRow(item) + + +if __name__ == '__main__': + import sys + import cgitb + sys.excepthook = cgitb.enable(1, None, 5, '') + from PyQt5.QtWidgets import QApplication + app = QApplication(sys.argv) + w = Window() + w.show() + sys.exit(app.exec_())