python - QTableView:如何按行索引(标题索引-1)对TableView中的输入数据进行排序?
问题描述
我正在与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_()
截屏:
谢谢你。
解决方案
问题是 sort 方法对数据进行排序并且转换是不可逆的,以前的解决方案使用代理,这对视觉部分而不是数据进行排序,所以最后在其他解决方案的情况下,避免重新排序就足够了并显示原始数据。
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_()
推荐阅读
- android - 布局方向为 rtl 时按钮改变方向
- c# - 如何使用 BouncyCastle c# 将 RSA 公钥转换为字符串
- jquery - 如何调试 JSON.stringify 报告的循环引用
- javascript - 为什么改变函数return的值会改变函数console.log的结果?
- c++ - 在 Windows 10 中将 GSL 库链接到 RcppGSL
- android - 为什么图标看起来很小?以及如何解决?
- java - 数据截断:截断不正确的 DOUBLE 值:'Id'
- swift - 使 Completionhandler 在 For 循环中工作以获取图像
- javascript - 是否可以使用 React.Component 仅包含 react 和 reactDom 作为 html 中的标签?
- jpa - Aries JPA EntityManager 服务未针对 WebLogic 数据源启动