目录
简述
通过QIdentityProxyModel,根据不同需求提供不同的数据展示(如示例中只显示姓名和年龄数据,不显示性别数据或者改改字体,等等等,这些操作都不会更改原始数据)。
不同于QSortFilterProxyModel,没有现成的排序和过滤可以使用。
而QTransposeProxyModel则可以横纵反向。
它们都继承自QAbstractProxyModel。
自定义QIdentityProxyModel
class StuProxy(QIdentityProxyModel): # 自定义QIdentityProxyModel
def rowCount(self, index=QModelIndex()) -> int:
return 3 # 定制行数
def columnCount(self, index=QModelIndex()) -> int:
return 2 # 定制列数
def headerData(self, section: int, orientation: Qt.Orientation, role: int = ...) -> str:
if role != Qt.ItemDataRole.DisplayRole:
return None
if orientation == Qt.Orientation.Horizontal: # 水平表头
return f'{[self.sourceModel().horizontalHeaderItem(i).text() for i in range(self.sourceModel().columnCount())][section]}'
elif orientation == Qt.Orientation.Vertical: # 垂直表头
return f'第{section+1}行'
def data(self, proxyIndex, role: int = ...) -> object:
if role == Qt.ItemDataRole.FontRole: # 字体
return QFont('sans-serif', 24)
elif role == Qt.ItemDataRole.BackgroundRole: # 背景
return QColor(Qt.GlobalColor.gray)
elif role != Qt.ItemDataRole.DisplayRole and role != Qt.ItemDataRole.EditRole:
return None
return self.sourceModel().index(proxyIndex.row(), proxyIndex.column()).data()
def mapFromSource(self, sourceIndex) -> QModelIndex:
if sourceIndex.isValid():
return self.createIndex(sourceIndex.row(), sourceIndex.column()) # proxy进行创建QModelIndex
return QModelIndex()
def mapToSource(self, proxyIndex) -> QModelIndex:
if proxyIndex.isValid():
return self.sourceModel().createIndex(proxyIndex.row(), proxyIndex.column()) # source进行创建QModelIndex
return QModelIndex()
主窗体
class StuWin(QWidget):
def __init__(self):
super().__init__()
self.stu_lis = [['学习1', 17, '女'],['学习2', 27, '男'],['学习3', 37, '男'],['学习4', 47, '男'],['学习5', 57, '男']] # 数据
self.initUI()
def initUI(self):
self.setWindowTitle('学习练习')
self.move_center(600, 400)
layout = QVBoxLayout()
model = QStandardItemModel() # 模型
model.setRowCount(3)
model.setColumnCount(3)
model.setHorizontalHeaderLabels(['姓名', '年龄', '性别'])
for rowIndex, row in enumerate(self.stu_lis):
for colIndex, col in enumerate(row):
model.setItem(rowIndex, colIndex, QStandardItem(str(col))) # 模型添加数据
proxy = StuProxy() # 自定义代理
proxy.setSourceModel(model)
view = QTableView() # 视图
view.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
view.setSelectionBehavior(QTableView.SelectionBehavior.SelectRows) # 选整行
view.setEditTriggers(QTableView.EditTrigger.NoEditTriggers) # 编辑进制
view.setModel(proxy)
layout.addWidget(view)
self.setLayout(layout)
def move_center(self, width, height):
w = QGuiApplication.primaryScreen().size().width()
h = QGuiApplication.primaryScreen().size().height()
self.setGeometry((w - width) / 2, (h - height) / 2, width, height)
运行效果
问题
1、headerData(...)函数中,将水平表头写死为return f'{["姓名", "年龄", "性别"][section]}',是无法展示数据的,