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

Maurizio Berti maurizio.berti at gmail.com
Wed Feb 6 13:32:19 GMT 2019


>
> If I did not make it clear I would remind you of one of my findings.  I
> start with Python datetime.date variables.  I populate the model via setData(index,
> dateValue) (no role specified, so EditRole).  At this point no sorting
> happens.  However, all I have to do is change that to setData(index,
> QDate(dateValue)) and it *does* then work, so no "need to provide your
> own method".
>

> Why is that?  From
> http://doc.qt.io/qt-5/qsortfilterproxymodel.html#lessThan I am told that
> the sorting deals in QVariant types, and QMetaType::QDate is among those
> it handles.  Now, you know much better than I, but everywhere else I use
> PyQt it seems to convert between Python types and necessary QVariant
> types invisibly and all is well, but not here?  Why not?
>
>
Well, that's interesting: I've always assumed that the DisplayRole wouldn't
accept data other than strings and numbers, but you made me realize that it
can actually store any data that "supports" printable form (which
QDate/Time do). Of course, this could be a small issue if you want a
different string format for dates, but if the default one suits your needs,
that's fine.
Since lessThan supports a small set of QVariant types (including
QDate/Time) and we can use that QVariant type as a Display role, it's good
enough.
Besides that, I tried to use setData with random QDateTimes converted QDate
using their date() method, and it seems to work fine, without using
QDate(dateValue) you mentioned.
To be clear, I tested with this code:

sourceModel.setData(
    sourceModel.index(row, 0),

QtCore.QDateTime().currentDateTime().addDays(-randrange(30)).addSecs(-randrange(86400)).date())

I'm using an old Qt 5.7.1, it's possible that it's a regression, have you
checked up on QtBugs?



> I'm also a little lost about QStandardItem vs QStandardItemModel, if
> that's significant.  My code creates the (source) model as a
> QStandardItemModel.  That claims to use
> http://doc.qt.io/qt-5/qstandarditemmodel.html#setData,whose default role
> is EditRole.  Nowhere do I create a QStandardItem explicitly, whose
> http://doc.qt.io/qt-5/qstandarditem.html#setData uses default role is UserRole
> + 1.  So now I'm not sure which I am using, though I would think only
> QStandardItemModel?  Is this of relevance to my issue?
>

Well, I've always used empty models at start and fill them as needed, since
I mostly use dynamic models or prefer to create data in this way. But
that's one way.
It doesn't change much from creating a model (even specifying the size, if
you can) and then create new rows/columns and setting the data directly
from the model.
In this case, the QStandardItems do not exist until the internal indexes
are created (trying to access any index is enough, for example by setting
or reading data): if you try to access a item(0, 0) on a new
QStandardItemModel with a specified size, it will return None. If you try a
itemFromIndex(model.index(0,0)) it will return an item.
That said, I don't think it would change much in your case, as soon as you
always use the right role when setting data. I think that the default
UserRole + 1 of item.setData is just for convenience, but since you always
use the model.setData methods that wouldn't be an issue anyway.

Maurizio

-- 
È 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/20190206/b95ee9ad/attachment.html>


More information about the PyQt mailing list