我正在使用Pyside2,Python 3.8
我有一个 QTableView,带有 QSortFilterProxyModel 模型。我设法在单个列上对行进行排序。我想要实现的是将 myTableView 在第 3 列(包含字符串数据)上排序,然后在第 2 列(包含布尔数据)上排序,然后在第 4 列(包含整数数据)上排序。请参阅下图示例
我一直在尝试不同的原因,似乎黑客是在 lessThan() 方法中,但这对我来说非常困惑。
有人可以给我一个提示,告诉我应该如何进行吗?
这是我的代码的一些示例,如果对任何人有帮助的话。
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
ProxyModel = ProxyModel()
TableModel = TableModel()
ProxyModel.setSourceModel(TableModel)
self.MyTableView.setModel(ProxyModel)
class ProxyModel(QtCore.QSortFilterProxyModel):
def __init__(self,parent=None):
super(ProxyModel, self).__init__()
self._filter = "Aucun"
def filterAcceptsRow(self, sourceRow, sourceParent):
if self._filter == "Aucun": return True
sourceModel = self.sourceModel()
id = sourceModel.index(sourceRow, self.filterKeyColumn(), sourceParent)
if sourceModel.data(id) == self._filter:
return True
return False
def lessThan(self, left, right):
print(left.row(), ' vs ',right.row())
if left.column() == 3:
leftData = int(self.sourceModel().data(left))
rightData = int(self.sourceModel().data(right))
if left.column() == 2:
leftData = str(self.sourceModel().data(left))
rightData = str(self.sourceModel().data(right))
return leftData < rightData
class TableModel(QtCore.QAbstractTableModel):
def __init__(self, mlist=None):
super(TableModel, self).__init__()
self._items = [] if mlist == None else mlist
self._header = []
def rowCount(self, parent = QtCore.QModelIndex):
return len(self._items)
def columnCount(self, parent = QtCore.QModelIndex):
return len(self._header)
def data(self, index, role = QtCore.Qt.DisplayRole):
if not index.isValid():
return None
if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole:
return self._items[index.row()][index.column()]
return None
def setData(self, index, value, role = QtCore.Qt.EditRole):
if value is not None and role == QtCore.Qt.EditRole:
self._items[index.row()-1][index.column()] = value
self.dataChanged.emit(index, index)
return True
return False
def addRow(self, rowObject):
row = self.rowCount()
self.beginInsertRows(QtCore.QModelIndex(), row, row)
self._items.append(rowObject)
self.endInsertRows()
self.layoutChanged.emit()
QSortFilterProxyModel
和
lessThan
的每个行对,
index(left_row, sort_column)
仅调用一次 index(right_row, sort_column)
,因此实现必须考虑到这一点。忽略列部分并访问您感兴趣的列。
def lessThan(self, left, right):
row1 = left.row()
row2 = right.row()
model = left.model()
for col in [3,2,4]:
a = model.data(model.index(row1, col))
b = model.data(model.index(row2, col))
if a < b:
return True
elif a > b:
return False
return True
我找到了一个非常快速且不那么脏的替代方案:只需首先对辅助列进行排序(根据需要升序/降序),然后对主列进行排序。看起来,好像排序算法在内部从第一个条目到最后一个条目工作:)