Reputation: 834
I have a QTableView with a subclassed QSqlQueryModel and a QSortFilterProxyModel in between. Some columns in the underlying database contain floating point numbers and they get sorted as they were strings. Example:
-0.06
-1.45
0.02
0.05
...
Using Python/PyQt, I implemented the outlined solution from this accepted answer but it doesn't work.
My subclassed QSqlQueryModel:
class CatalogModel(QSqlQueryModel):
SortRole = Qt.UserRole + 1
def data(self, index, role=Qt.DisplayRole):
col = index.column()
data = super(CatalogModel, self).data(index, role)
print role == self.SortRole # always False
if role == self.SortRole:
if col in (2,3,4):
return data.toFloat()[0]
return data
Setting up the proxy:
proxy = QSortFilterProxyModel(self)
proxy.setSortRole(CatalogModel.SortRole)
My own SortRole does not arrive in my model and the columns with float numbers are still sorted like strings. Why does this solution not work? Did I miss something?
Upvotes: 1
Views: 2371
Reputation: 7954
You need to switch sorting on I think. Something like:
proxy.sort(-1, Qt.AscendingOrder);
According to docs http://doc.qt.io/qt-4.8/qsortfilterproxymodel.html column -1
will switch on the sorting of the underlying model. Which is probably what you need.
Upvotes: 0
Reputation: 53173
From the latest official documentation:
Behind the scene, the view calls the sort() virtual function on the model to reorder the data in the model. To make your data sortable, you can either implement sort() in your model, or use a QSortFilterProxyModel to wrap your model -- QSortFilterProxyModel provides a generic sort() reimplementation that operates on the sortRole() (Qt::DisplayRole by default) of the items and that understands several data types, including int, QString, and QDateTime. For hierarchical models, sorting is applied recursively to all child items. String comparisons are case sensitive by default; this can be changed by setting the sortCaseSensitivity property.
Implement your own sort() could also be one option, but:
An alternative approach to sorting is to disable sorting on the view and to impose a certain order to the user. This is done by explicitly calling sort() with the desired column and order as arguments on the QSortFilterProxyModel (or on the original model if it implements sort()). For example:
proxyModel->sort(2, Qt::AscendingOrder);
QSortFilterProxyModel can be sorted by column -1, in which case it returns to the sort order of the underlying source model.
You could pass -1 to that method in the following manner:
proxy = QSortFilterProxyModel(self);
proxy.setSortRole(CatalogModel.SortRole);
proxy.sort(-1, Qt.AscendingOrder);
Note that you pasted the two lines there without semi-colon. The code would not even compile like that due to syntax errors. It is better to paste correct code.
If it does not work, just implement your sorting.
Upvotes: 1