I am using PyQt4 and have a QTableView
with a 2 columns data.
There is an extra column for an index (it comes from the headerData
function of the source model). For sorting when clicking on the header buttons I wrap my model with a proxy class.
That's working fine, but I also want to sort by the first column by clicking on the left-top corner button (column number: "-1" I would say)
:
As requested, here is a minimal example:
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_())
Can someone please help me?
First you must be able to get the cornerWidget
which is a QAbstractButton
, for that we use findChild
. Then we use sort(-1)
that invalidates the ordering and places it in the initial state.
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))