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

J Barchan jnbarchan at gmail.com
Wed Feb 6 15:27:00 GMT 2019


On Wed, 6 Feb 2019 at 14:47, Maurizio Berti <maurizio.berti at gmail.com>
wrote:

> This does not matter now, in that I have a workaround, but I'll ask you
>> one more time.  The example you give talks about converting QDateTimes
>> to QDates.  Please forget about QDateTime, that is not the issue I am
>> asking about.  As long as your original code only uses the Qt native types
>> like QDate or QDateTime there will be no problem sorting.  I understand
>> that.
>>
>> My code uses the *Python* types from the datetime module.  datetime.date
>> is a Python date type.  In all other places I have made PyQt calls it
>> always correctly converts between, say, Python type datetime.date and Qt
>> type QDate, in either direction, as necessary.  I do not have to do
>> anything special in my code.  The PyQt wrappers for arguments etc. are
>> doing it for me.  This is a huge (good) point about PyQt.
>>
>
> I'm sorry, Jonathan: I think I didn't read your first message carefully
> enough, and then I didn't take the "Python type datetime" into account.
>
> The *only* question I do not understand/would like answered is: why do I
>> have to use QDate and not datetime.date in the model to make just Q
>> SortFilterProxyModel::sort() work, when everything other than that works
>> fine with datetime.date?  Why does PyQt auto-conversion between Python
>> datetime.date and Qt QDate work everywhere other than during
>> QSortFilterProxyModel.sort()?
>>
>
> Well, I'm just guessing an answer here; it's possible that in every other
> situation the conversion is done automatically since you're doing
> operations involving unambiguous treatment of the date object, for example
> when setting a QDateTimeEdit date, or, in this case, display the date in
> the table field.
> The sort() method instead attempts to sort by "guessing" the preferred
> sorting criteria according to the content of the field, which is not
> unique. You could have strings, floats and datetimes in the same column and
> *maybe* that's why the automatic conversion doesn't work properly in this
> case: while QDateTime is directly recognized by lessThan() along with other
> QVariant types, Python's datetime is not "native" to Qt and I suppose that
> it just doesn't know what to do with it (do you want to compare it as a
> string? as a number? as a QDate? as a QDateTime?), then I think it just
> "leaves" the object as it is, without doing any comparison.
>
> Again, this is just a guess, tonight I'll check the sources and maybe I'll
> find out a better answer.
>
> Maurizio
>
> --
> È difficile avere una convinzione precisa quando si parla delle ragioni
> del cuore. - "Sostiene Pereira", Antonio Tabucchi
> http://www.jidesk.net
>

Hi Maurizio,

tonight I'll check the sources and maybe I'll find out a better answer.
>

That would be most interesting to me, if you feel like doing it.

Think of this.  When I go model.setData(row, col, python_date), the C++
definition for setData() takes a QVariant for the value.  Somewhere along
the line, PyQt auto-converts Python datetime.date to a QVariant of type
QMetaType::QDate containing a QDate, right?  (And similarly unwraps if I
call model.data(row, col).)  At least that's my understanding.

When I go SortFilterProxyModel::sort(), I read the documentation at
http://doc.qt.io/qt-5/qsortfilterproxymodel.html#lessThan.  I see
QMetaType::QDate among the QVariant types it says it can handle.  When it
comes to compare the values in my model, I'm *expecting* it to similarly
come across my Python datetime.date values and auto-convert them to that
QVariant which it knows it can handle.  But it does not appear to do that.

Meanwhile, that doc states it can also handle QMetaType::QString.  QString
is also a Qt type, not a Python one.  But I don't bother to put QStrings
into my model, I just put in plain Python strs, *and yet I find that those
do sort*.  Why is that OK but the date ones not?

(Hmm, I'm beginning to wonder/think: the example I gave with
setData()/data() it must do whatever converting on the argument/return
result there & then, from/to Python.  With the SortFilterProxyModel::sort(),
encountering values is going on *during* the sort, which is written in C++,
so that code will not know about Python type conversions.  Is this what
it's all about, the reason why no conversion takes place during sort()
only?)

To make it even more confusing.  The above doc link for
SortFilterProxyModel::lessThan() states:

Any other type will be converted to a QString
> <http://doc.qt.io/qt-5/qstring.html> using QVariant::toString
> <http://doc.qt.io/qt-5/qvariant.html#toString>().
>

I therefore thought if my native Python datetime.date was "not recognised",
it would at minimum do a string sort.  Might not be what I intended for my
dates, but at least I'd see something happening in the way of reordering.
Instead, I see nothing gets moved, the original order is simply preserved,
just as though for whatever reason the sort has done nothing.  No
complaints, just nothing happens.

Thanks for your time!



-- 
Kindest,
Jonathan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20190206/2515b0fa/attachment-0001.html>


More information about the PyQt mailing list