QTableView:按 header 索引 -1 排序
QTableView: sort by header index -1
我正在使用 PyQt4 并有一个包含 2 列数据的 QTableView
。
索引有一个额外的列(它来自源模型的 headerData
函数)。为了在单击 header 按钮时进行排序,我用代理 class 包裹了我的模型。
工作正常,但我还想通过单击 left-top 角按钮按第一列排序 (column number: "-1" I would say)
:
根据要求,这是一个最小的例子:
from PyQt4 import QtCore, QtGui
import random, sys
class MyModel(QtCore.QAbstractTableModel):
headers = 'Name', 'Value'
def __init__(self, parent=None):
super(MyModel, self).__init__(parent)
# Dummy data
rows = []
columns = []
for i in range(10):
numbr = random.randint(1,20)
rows.append('Name #%i' % numbr)
columns.append('Value #%i' % numbr)
self.data = zip(rows, columns)
def columnCount(self, parent=QtCore.QModelIndex()):
return 2
def rowCount(self, parent=QtCore.QModelIndex()):
return len(self.data)
def data(self, index, role=QtCore.Qt.DisplayRole):
if not index.isValid():
return None
if (index.row() >= len(self.data)) or (index.row() < 0):
return None
if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole:
return self.data[index.row()][index.column()]
return None
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 MyProxyModel(QtGui.QSortFilterProxyModel):
def __init__(self):
super(MyProxyModel, self).__init__()
def lessThan(self, left_index, right_index):
left_var = left_index.data(QtCore.Qt.EditRole)
right_var = right_index.data(QtCore.Qt.EditRole)
# Column #1 (values) should be not sortable
if left_index.column() == 1:
return False
return left_var < right_var
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.model = MyModel()
self.proxy = MyProxyModel()
self.proxy.setSourceModel(self.model)
self.proxy.setFilterKeyColumn(0)
self.selectionModel = QtGui.QItemSelectionModel(self.proxy)
self.tableView = QtGui.QTableView()
self.tableView.setModel(self.proxy)
self.tableView.setSelectionModel(self.selectionModel)
self.tableView.setSortingEnabled(True)
self.tableView.sortByColumn(0, QtCore.Qt.AscendingOrder)
self.setCentralWidget(self.tableView)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
有人可以帮我吗?
首先你必须能够得到cornerWidget
,这是一个QAbstractButton
,为此我们使用findChild
。然后我们使用 sort(-1)
使排序无效并将其置于初始状态。
class MainWindow(QtGui.QMainWindow):
def __init__(self):
...
self.setCentralWidget(self.tableView)
cornerButton = self.tableView.findChild(QtGui.QAbstractButton)
cornerButton.clicked.connect(lambda: self.proxy.sort(-1))
我正在使用 PyQt4 并有一个包含 2 列数据的 QTableView
。
索引有一个额外的列(它来自源模型的 headerData
函数)。为了在单击 header 按钮时进行排序,我用代理 class 包裹了我的模型。
工作正常,但我还想通过单击 left-top 角按钮按第一列排序 (column number: "-1" I would say)
:
根据要求,这是一个最小的例子:
from PyQt4 import QtCore, QtGui
import random, sys
class MyModel(QtCore.QAbstractTableModel):
headers = 'Name', 'Value'
def __init__(self, parent=None):
super(MyModel, self).__init__(parent)
# Dummy data
rows = []
columns = []
for i in range(10):
numbr = random.randint(1,20)
rows.append('Name #%i' % numbr)
columns.append('Value #%i' % numbr)
self.data = zip(rows, columns)
def columnCount(self, parent=QtCore.QModelIndex()):
return 2
def rowCount(self, parent=QtCore.QModelIndex()):
return len(self.data)
def data(self, index, role=QtCore.Qt.DisplayRole):
if not index.isValid():
return None
if (index.row() >= len(self.data)) or (index.row() < 0):
return None
if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole:
return self.data[index.row()][index.column()]
return None
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 MyProxyModel(QtGui.QSortFilterProxyModel):
def __init__(self):
super(MyProxyModel, self).__init__()
def lessThan(self, left_index, right_index):
left_var = left_index.data(QtCore.Qt.EditRole)
right_var = right_index.data(QtCore.Qt.EditRole)
# Column #1 (values) should be not sortable
if left_index.column() == 1:
return False
return left_var < right_var
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.model = MyModel()
self.proxy = MyProxyModel()
self.proxy.setSourceModel(self.model)
self.proxy.setFilterKeyColumn(0)
self.selectionModel = QtGui.QItemSelectionModel(self.proxy)
self.tableView = QtGui.QTableView()
self.tableView.setModel(self.proxy)
self.tableView.setSelectionModel(self.selectionModel)
self.tableView.setSortingEnabled(True)
self.tableView.sortByColumn(0, QtCore.Qt.AscendingOrder)
self.setCentralWidget(self.tableView)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
有人可以帮我吗?
首先你必须能够得到cornerWidget
,这是一个QAbstractButton
,为此我们使用findChild
。然后我们使用 sort(-1)
使排序无效并将其置于初始状态。
class MainWindow(QtGui.QMainWindow):
def __init__(self):
...
self.setCentralWidget(self.tableView)
cornerButton = self.tableView.findChild(QtGui.QAbstractButton)
cornerButton.clicked.connect(lambda: self.proxy.sort(-1))