forked from PyQt5/PyQt
-
Notifications
You must be signed in to change notification settings - Fork 6
/
CustomWidgetSortItem.py
119 lines (98 loc) · 3.94 KB
/
CustomWidgetSortItem.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on 2018年8月4日
@author: Irony
@site: https://pyqt.site , https://github.com/PyQt5
@email: [email protected]
@file: QListView.显示自定义Widget并排序
@description:
"""
import string
from random import choice, randint
from time import time
try:
from PyQt5.QtCore import QSortFilterProxyModel, Qt, QSize
from PyQt5.QtGui import QStandardItem, QStandardItemModel
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QPushButton, QListView, \
QHBoxLayout, QLineEdit, QApplication
except ImportError:
from PySide2.QtCore import QSortFilterProxyModel, Qt, QSize
from PySide2.QtGui import QStandardItem, QStandardItemModel
from PySide2.QtWidgets import QWidget, QVBoxLayout, QPushButton, QListView, \
QHBoxLayout, QLineEdit, QApplication
def randomChar(y):
# 返回随机字符串
return ''.join(choice(string.ascii_letters) for _ in range(y))
class CustomWidget(QWidget):
def __init__(self, text, *args, **kwargs):
super(CustomWidget, self).__init__(*args, **kwargs)
layout = QHBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
layout.addWidget(QLineEdit(text, self))
layout.addWidget(QPushButton('x', self))
def sizeHint(self):
# 决定item的高度
return QSize(200, 40)
class SortFilterProxyModel(QSortFilterProxyModel):
def lessThan(self, source_left, source_right):
if not source_left.isValid() or not source_right.isValid():
return False
# 获取数据
leftData = self.sourceModel().data(source_left)
rightData = self.sourceModel().data(source_right)
if self.sortOrder() == Qt.DescendingOrder:
# 按照时间倒序排序
leftData = leftData.split('-')[-1]
rightData = rightData.split('-')[-1]
return leftData < rightData
# elif self.sortOrder() == Qt.AscendingOrder:
# #按照名字升序排序
# leftData = leftData.split('-')[0]
# rightData = rightData.split('-')[0]
# return leftData < rightData
return super(SortFilterProxyModel, self).lessThan(source_left, source_right)
class Window(QWidget):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(*args, **kwargs)
self.resize(800, 600)
layout = QVBoxLayout(self)
# 名字排序
layout.addWidget(QPushButton('以名字升序', self, clicked=self.sortByName))
# 时间倒序
layout.addWidget(QPushButton('以时间倒序', self, clicked=self.sortByTime))
# listview
self.listView = QListView(self)
layout.addWidget(self.listView)
# 数据模型
self.dmodel = QStandardItemModel(self.listView)
# 排序代理模型
self.fmodel = SortFilterProxyModel(self.listView)
self.fmodel.setSourceModel(self.dmodel)
self.listView.setModel(self.fmodel)
# 模拟生成50条数据
for _ in range(50):
name = randomChar(5)
times = time() + randint(0, 30) # 当前时间随机+
value = '{}-{}'.format(name, times) # 内容用-分开
item = QStandardItem(value)
# item.setData(value, Qt.UserRole + 2)
self.dmodel.appendRow(item)
# 索引
index = self.fmodel.mapFromSource(item.index())
# 自定义的widget
widget = CustomWidget(value, self)
item.setSizeHint(widget.sizeHint())
self.listView.setIndexWidget(index, widget)
def sortByTime(self):
# 按照时间倒序排序
self.fmodel.sort(0, Qt.DescendingOrder)
def sortByName(self):
# 按照名字升序排序
self.fmodel.sort(0, Qt.AscendingOrder)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
w = Window()
w.show()
sys.exit(app.exec_())