QTableView: Как отсортировать входные данные в TableView по индексу строки (индекс заголовка -1)? - PullRequest
0 голосов
/ 29 июня 2018

Я работаю с QTableView. Я могу сортировать данные на основе отдельных заголовков столбцов как по возрастанию, так и по убыванию. После того, как я отсортирую данные по заголовку столбца, я хотел бы снова отсортировать их на основе исходного индекса. Я пытался подписаться на этот вопрос , но не смог его исправить.

Код:

import numpy as np
from qtpy import QtCore, QtGui, QtWidgets
from qtpy.QtCore import Qt, QAbstractTableModel
from qtpy.QtWidgets import QApplication, QTableView

data = np.random.random((10, 3))

app = QApplication([''])


class SimpleModel(QAbstractTableModel):

    headers = 'Col 1', 'Col 2', 'Col 3'

    def __init__(self, *args, **kwargs):
        super(SimpleModel, self).__init__(*args, **kwargs)
        table.setSortingEnabled(True)
        self.order = np.arange(data.shape[0])
        self.layoutChanged.emit()

    def rowCount(self, index=None):
        return 10

    def columnCount(self, index=None):
        return 3

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

    def sort(self, column, ascending):
        self.order = np.argsort(data[:, column])
        if ascending == Qt.DescendingOrder:
            self.order = self.order[::-1]
        self.layoutChanged.emit()

    def headerData(self, section, orientation, role):
        if role == QtCore.Qt.DisplayRole :
            if orientation == QtCore.Qt.Horizontal :
                return self.headers[section]
            elif orientation == QtCore.Qt.Vertical :
                return section
        return None


table = QTableView()
table.setModel(SimpleModel())
table.show()

app.exec_()

Скриншот:

enter image description here

Спасибо.

1 Ответ

0 голосов
/ 02 июля 2018

Проблема в том, что метод сортировки упорядочивает данные, и это преобразование является необратимым, предыдущее решение использует прокси, это упорядочивает визуальную часть, но не данные, поэтому, в конце концов, в случае другого решения этого достаточно чтобы избежать переупорядочения и показать исходные данные.

import numpy as np
from qtpy import QtCore, QtGui, QtWidgets

data = np.random.random((10, 3))*10 -9

app = QtWidgets.QApplication([''])


class SimpleModel(QtCore.QAbstractTableModel):

    headers = 'Col 1', 'Col 2', 'Col 3'

    def __init__(self, *args, **kwargs):
        super(SimpleModel, self).__init__(*args, **kwargs)
        table.setSortingEnabled(True)
        self.order = np.arange(data.shape[0])
        self.layoutChanged.emit()

    def rowCount(self, index=None):
        return 10

    def columnCount(self, index=None):
        return 3

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

    def headerData(self, section, orientation, role):
        if role == QtCore.Qt.DisplayRole :
            if orientation == QtCore.Qt.Horizontal :
                return self.headers[section]
            elif orientation == QtCore.Qt.Vertical :
                return section
        return None

class SortProxyModel(QtCore.QSortFilterProxyModel):
    def lessThan(self, left_index, right_index):
        left_var = self.sourceModel().data(left_index)
        right_var = self.sourceModel().data(right_index)
        return float(left_var) < float(right_var)


table = QtWidgets.QTableView()
model = SimpleModel()
proxy = SortProxyModel()
proxy.setSourceModel(model)
table.setModel(proxy)
table.show()
cornerButton = table.findChild(QtWidgets.QAbstractButton)
cornerButton.clicked.connect(lambda: proxy.sort(-1))
app.exec_()
...