[PyQt] QSortFilterProxyModel::sort() not sorting on column types

Maurizio Berti maurizio.berti at gmail.com
Fri Feb 1 20:49:14 GMT 2019


To correctly support sorting for non string values you need to provide your
own method.
Also, for numeric values ensure that the data is stored as a number and not
as string. For QStandardItemModel you can achieve that by creating
QStandardItems without any data value, and then set the numeric data using
QStandardItem.setData(value, QtCore.Qt.DisplayValue); remember that the
role must be specified, as the setData method of QStandardItem uses the
UserRole + 1 role by default. This will solve the sorting for your float
column.

To sort by date, it's better to set the QDateTime value as a custom role
(>=UserRole) and store the object as it is, while you can choose to set the
displayed string once you create the QStandardItems or by using an item
delegate, if you need a visual representation.
After that just implement the lessThan() method of QSortFilterProxyModel,
which allows to customize how the items are sorted whenever the sort()
method is called.

Supposing that you're using the second column for the QDateTime items and
you're using a role DateRole = QtCore.Qt.UserRole + 1:

class SortModel(QtCore.QSortFilterProxyModel):
    def lessThan(self, left, right):
        if left.column() == right.column() and left.column() == 1:
            return left.data(DateRole) < right.data(DateRole)
        return QtCore.QSortFilterProxyModel.lessThan(self, left, right)

class MyWidget(QtWidgets.QWidget):
    def __init__(self, *args, **kwargs):
        QtWidgets.QWidget.__init__(self, *args, **kwargs)
        [...]
        self.sourceModel = QtGui.QStandardItemModel()
        self.sortModel = SortModel()
        self.someTable.setModel(self.sortModel)
        self.sortModel.setSourceModel(self.sourceModel)

    def appendFields(self):
        floatItem = QtGui.QStandardItem()
        floatItem.setData(self.getSomeFloatNumber(), QtCore.Qt.DisplayRole)
        someDate = QtCore.QDateTime.currentDateTime()
        item = QtGui.QStandardItem(someDate.toString())
        item.setData(someDate, DateRole)
        self.sourceModel.appendRow([floatItem, dateItem])

I've tested it on an old 5.7.1, but from what you are experiencing it is
not a bug, but the expected behavior, since you didn't correctly implement
the sorting method and/or didn't provide a correct way for Qt to interpret
data for its default sorting rules.

Regards,
Maurizio



Il giorno ven 1 feb 2019 alle ore 10:45 J Barchan <jnbarchan at gmail.com> ha
scritto:

> I use Qt/PyQt 5.7, the standard distribution supplied for Ubuntu 18.04.
>
> I have a QSortFilterProxyModel wrapped around a QStandardItemModel as its
> source model.  I try to use QSortFilterProxyModel::sort() to sort by
> column values.
>
> I have a column of Python type datetime.date.  When I call the sort(),
> there is no "warning" but *nothing happens*.  The sort does not rearrange
> the items at all.  They are initially "randomly" ordered in rows, and the
> rows simply retain their current order.  It does *not* even reorder by
> string value.  It is as though it simply decides they are "unorderable".
>
> When I sort instead by a Python str column they *do* get reordered.
> FWIW, I have another column of Python type decimal.Decimal and sorting by
> that too does nothing, even though I think that should be convertible to
> float/double.  However, that may complicate matters so let's stick to the
> datetime.date case, I am just mentioning it in case it's relevant.
>
> It took me a long time to realise where the problem lies.  I have a
> workaround: I *explicitly* change all my values in the model from
> datetime.date to QDate(value) and now it does sort.
>
> But my understanding/experience from other PyQt methods is that it does
> this kind of Python type -> QVariant conversion for you behind the scenes
> itself.  I shouldn't have to change my types or write special code.
>
> Is this a bug?  Is this in my PyQt 5.7 only?
>
> --
> Kindest,
> Jonathan
> _______________________________________________
> PyQt mailing list    PyQt at riverbankcomputing.com
> https://www.riverbankcomputing.com/mailman/listinfo/pyqt
>


-- 
È difficile avere una convinzione precisa quando si parla delle ragioni del
cuore. - "Sostiene Pereira", Antonio Tabucchi
http://www.jidesk.net
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20190201/62ca999b/attachment.html>


More information about the PyQt mailing list