<div dir="ltr"><div dir="ltr"><div dir="ltr">Il giorno mer 6 feb 2019 alle ore 16:27 J Barchan <<a href="mailto:jnbarchan@gmail.com" target="_blank">jnbarchan@gmail.com</a>> ha scritto:</div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div><div style="font-family:tahoma,sans-serif">Think of this.  When I go <span style="font-family:monospace,monospace">model.setData(row, col, python_date)</span>, the C++ definition for <span style="font-family:monospace,monospace">setData()</span> takes a <span style="font-family:monospace,monospace">QVariant</span> for the value.  Somewhere along the line, PyQt auto-converts Python <span style="font-family:monospace,monospace">datetime.date</span> to a <span style="font-family:monospace,monospace">QVariant</span> of type <span style="font-family:monospace,monospace">QMetaType::QDate</span> containing a <span style="font-family:monospace,monospace">QDate</span>, right?  (And similarly unwraps if I call <span style="font-family:monospace,monospace">model.data(row, col)</span>.)  At least that's my understanding.</div></div></div></div></blockquote><div><br></div><div>Nope :-)<br>Any kind of object can be assigned to a (any) DataRole to a valid QModelIndex. I don't know how it works on C++ specifically (I think it doesn't change that much), but in the PyQt world whenever you setData() with a Python object as argument, the object remains intact and is stored in the model as it is, despite the type of the object itself (or, probably, a "PyQtObject" as it was called for PyQt4 and SIP version 1, which probably is a special PyQt "variant" of QVariant, but I'm just guessing here - anyway, it's returned in its original form when accessed).</div><div>The conversion to a Qt type is only done whenever it's needed, and is usually automatic and transparent to the Python interface.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div><div style="font-family:tahoma,sans-serif">Meanwhile, that doc states it can also handle <span style="font-family:monospace,monospace">QMetaType::QString</span>.  <span style="font-family:monospace,monospace">QString</span> is also a Qt type, not a Python one.  But I don't bother to put <span style="font-family:monospace,monospace">QString</span>s into my model, I just put in plain Python <span style="font-family:monospace,monospace">str</span>s, <i>and yet I find that those <u>do</u> sort</i>.  Why is that OK but the date ones not?<br></div></div></div></div></blockquote><div><br></div><div>If you use SIP v2 (which is default on PyQt5, but can be set for PyQt4 as well as with other compatible types) the QString class is not available. You cannot even import it, as it doesn't exist at all: PyQt automatically treats all strings as QStrings and viceversa as it's done with numeric values - this means that Python strings "are" QStrings. Other and more "complex" object types are automatically converted whenever it's needed, but they original state is maintained, so a Python datetime is NOT a QDateTime, but can be used as it would.<br>While it can be a small issue (as some useful QString processing methods are obviously not available), it's a huge advantage since you don't have to convert everytime between Qt and Python objects. The standard SIPv1 mode of python objects in PyQt4 was a continuous headache, as you'd have always needed to use the toPyObject() conversion, also creating issues with the annoying differences and issues between Python 2's <font face="monospace, monospace">str</font> and <font face="monospace, monospace">unicode</font> types and conversions.</div><div>So, long story short, the sort() of strings works just because Python strings are "virtually" QStrings.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div><div style="font-family:tahoma,sans-serif"></div><div style="font-family:tahoma,sans-serif">To make it even more confusing.  The above doc link for <span style="font-family:monospace,monospace">SortFilterProxyModel::lessThan()</span> states:<br></div></div><div><div style="font-family:tahoma,sans-serif"><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="font-family:tahoma,sans-serif">Any other type will be converted to a <a href="http://doc.qt.io/qt-5/qstring.html" target="_blank">QString</a> using <a href="http://doc.qt.io/qt-5/qvariant.html#toString" target="_blank">QVariant::toString</a>().</div></blockquote></div></div></div></blockquote><div> </div><div>I think that, from the PyQt point of view, this means that it converts the object to a string only if the object is a known QVariant type that can be converted to a "QString". I'm not really sure about this, but I'm assuming this from the fact that other non-Qt objects are not converted to strings in models even when required (for example, displaying data in an item view), even if they do have a __str__() magic method implemented. Interestingly enough, the public toString() method of QVariant is not available on PyQt5 and cannot implemented therefore to create custom QVariant classes.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div><div style="font-family:tahoma,sans-serif"></div><div style="font-family:tahoma,sans-serif">I therefore thought if my native Python <span style="font-family:monospace,monospace">datetime.date</span> 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.</div></div></div></div></blockquote><div><br></div><div>Considering what explained before, you might agree that lessThan() cannot do any kind of sorting with "unknown" PyQt objects. It gets an unknown object, doesn't "know" how to sort it against another (even similar) object, then it leaves the order unsorted.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div><div style="font-family:tahoma,sans-serif">Thanks for your time!<br></div></div></div></div></blockquote><div><br></div><div>Thank you! Actively thinking about these problems helps having a better consciousness about how (PyQt) objects actually work. :-)</div><div></div></div><div><br></div>Maurizio<br clear="all"><div><br></div>-- <br><div dir="ltr" class="m_-1136118425909832373gmail_signature">È difficile avere una convinzione precisa quando si parla delle ragioni del cuore. - "Sostiene Pereira", Antonio Tabucchi<br><a href="http://www.jidesk.net" target="_blank">http://www.jidesk.net</a></div></div></div>