在 QTableView 中对多列进行排序

问题描述 投票:0回答:2

我正在使用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()
python pyside2
2个回答
2
投票
对于索引设置为

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

0
投票

我找到了一个非常快速且不那么脏的替代方案:只需首先对辅助列进行排序(根据需要升序/降序),然后对主列进行排序。看起来,好像排序算法在内部从第一个条目到最后一个条目工作:)

© www.soinside.com 2019 - 2024. All rights reserved.