python - QTableView排序时如何保留选择

标签 python pyside2 qtableview

当我对表格进行排序时,如何保留项目的选择?在下面的示例中,选择始终固定为行索引,即如果我选择第一行,则排序后始终选择第一行,而不是我选择的实际行。

import sys

from PySide2 import QtWidgets, QtGui, QtCore
from PySide2.QtCore import Qt


class TableModel(QtCore.QAbstractTableModel):
    def __init__(self, data):
        super().__init__()
        self._data = data

    def data(self, index, role):
        if role == Qt.DisplayRole:
            return self._data[index.row()][index.column()]

    def sort(self, column, order):
        if order == Qt.DescendingOrder:
            rev = True
        else:
            rev = False
        self.layoutAboutToBeChanged.emit()
        self._data.sort(key=lambda x: x[column], reverse=rev)
        self.layoutChanged.emit()

    def rowCount(self, parent=None):
        return len(self._data)

    def columnCount(self, parent=None):
        return len(self._data[0])


class Main(QtWidgets.QDialog):
    def __init__(self, data):
        super().__init__()
        self.layout = QtWidgets.QVBoxLayout()
        self.table = QtWidgets.QTableView()
        self.table.setSortingEnabled(True)
        self.table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows)
        self.model = TableModel(data)
        self.table.setModel(self.model)
        self.layout.addWidget(self.table)
        self.setLayout(self.layout)


def main():
    app = QtWidgets.QApplication(sys.argv)
    data = [
        [1,2,3,4],
        [5,6,7,8],
        [6,5,4,3],
        [2,1,0,9]
    ]
    m = Main(data)
    m.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

最佳答案

在实现排序方法时,您正在修改数据,并且 View 无法知道项目的新位置,您必须使用 QSortFilterProxyModel 修改索引,而不是修改数据:

import sys

from PySide2 import QtCore, QtGui, QtWidgets


class TableModel(QtCore.QAbstractTableModel):
    def __init__(self, data):
        super().__init__()
        self._data = data

    def data(self, index, role):
        if role == QtCore.Qt.DisplayRole:
            return self._data[index.row()][index.column()]

    def rowCount(self, parent=None):
        return len(self._data)

    def columnCount(self, parent=None):
        return len(self._data[0])


class Main(QtWidgets.QDialog):
    def __init__(self, data):
        super().__init__()
        self.layout = QtWidgets.QVBoxLayout()
        self.table = QtWidgets.QTableView()
        self.table.setSortingEnabled(True)
        self.table.setSelectionBehavior(
            QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows
        )
        self.model = TableModel(data)
        <b>self.proxy = QtCore.QSortFilterProxyModel()
        self.proxy.setSourceModel(self.model)
        self.table.setModel(self.proxy)</b>
        self.layout.addWidget(self.table)
        self.setLayout(self.layout)


def main():
    app = QtWidgets.QApplication(sys.argv)
    data = [[1, 2, 3, 4], [5, 6, 7, 8], [6, 5, 4, 3], [2, 1, 0, 9]]
    m = Main(data)
    m.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

关于python - QTableView排序时如何保留选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64317379/

相关文章:

Python AES解密例程(代码帮助)

python - pip install numpy 没有安装文件

python - 具有非同质任务的 Celery

python - 如何将 QTableWidget 中的数据绘制到 QChart 中

python - 有没有办法改变所有 QMessageBox 的 OK 按钮的样式表?

c++ - QTableView自动调整行高

python - 使用迭代项、上一项和下一项迭代列表时生成新列表

c++ - 为什么 QTableView 扩展选择会忽略我默认选择的行?

c++ - QTableView - 样本

python - 为什么当连接的槽显示 QMessageBox 时,editingFinished 信号会生成两次?