Custom sortable columns in QFileSystemModel
-
@Jo-Jo
Well, start by checking that goes through thetoDateTime()
path, what their values are and that is getting it right. I don't know what is wrong just by looking at it.Btw, check whether the
QString::localeAwareCompare(0
is case insensitive or case sensitive? Windows, but not Linux, sorts case insensitively, yours might not.You have just updated your code: I'm not sure it is any different from what you first wrote, but if it is and works that's fine.
-
@JonB Everything worked except for the "Date Modified" column. It turned out that Qt returns this date as a QString. I had to convert this string to QDateTime. Now the code looks like this:
class CustomSortFilterProxyModel : public QSortFilterProxyModel { QList<int> m_dtCols{3,4}; public: explicit CustomSortFilterProxyModel(QObject *parent = nullptr) : QSortFilterProxyModel(parent) {} protected: bool lessThan(const QModelIndex &left, const QModelIndex &right) const override { auto model = (QFileSystemModel*)sourceModel(); bool isLeftDir = model->isDir(left); bool isRightDir = model->isDir(right); if ((isLeftDir && isRightDir) || (!isLeftDir && !isRightDir)) { auto leftName = model->data(left, Qt::DisplayRole); auto rightName = model->data(right, Qt::DisplayRole); //return (leftName.toDateTime() < rightName.toDateTime()); // OK, works fine for dates if (m_dtCols.contains(sortColumn())) { if (sortColumn() == 3) { QDateTime dt1 = QDateTime::fromString(leftName.toString(), "M/d/yyyy h:mm AP"); QDateTime dt2 = QDateTime::fromString(rightName.toString(), "M/d/yyyy h:mm AP"); return dt1 < dt2; } return (leftName.toDateTime() < rightName.toDateTime()); } const int compare = QString::localeAwareCompare(leftName.toString(), rightName.toString()); if(compare != 0) { return compare < 0; } } else if (isLeftDir) { return true; } return false; } };
However, I'm not sure that I'm setting the date format correctly. It can change depending on the OS settings, or am I wrong?
-
@Jo-Jo said in Custom sortable columns in QFileSystemModel:
I had to convert this string to QDateTime
You already converted the QVariant to a QDateTime above - so why do you use the way through QString now again?
-
@Christian-Ehrlicher said in Custom sortable columns in QFileSystemModel:
You already converted the QVariant to a QDateTime above - so why do you use the way through QString now again?
Because "Date Modified" column is created by Qt and Qt using QString for this column. If I convert QVariant to QDateTime, in this case comparison does not work properly
-
Then you should debug why ... e.g. with a qDebug() statement as @JonB already wrote some time ago....
-
@Jo-Jo said in Custom sortable columns in QFileSystemModel:
Everything worked except for the "Date Modified" column. It turned out that Qt returns this date as a QString.
I am surprised at this, but untested. You are now talking about a "Date Modified" column inbuilt into
QFileSystemModel
, and not the "creation date" column you added for yourbirthTime()
? But that is QDateTime QFileSystemModel::lastModified(). So I don't understand where you are getting any string for a datetime which you need to convert. -
@JonB said in Custom sortable columns in QFileSystemModel:
You are now talking about a "Date Modified" column inbuilt into QFileSystemModel, and not the "creation date" column you added for your birthTime()?
Yes. This column value is QString, not QDateTime. You may check sources: https://codebrowser.dev/qt5/qtbase/src/widgets/dialogs/qfilesystemmodel.cpp.html#808
-
Thast's why https://doc.qt.io/qt-6/qfilesystemmodel.html#lastModified is there.
-
@Jo-Jo
I now see that, and see from https://codebrowser.dev/qt5/qtbase/src/widgets/dialogs/qfilesystemmodel.cpp.html#737 that it is called in the implementation ofQFileSystemModel::data()
for column #3, which is what I needed to know.I also see it is formatted as a string with
QLocale::ShortFormat
. I don't know what that looks like, I don't know how "precise" it is (e.g. down to, say, milliseconds or likely not?), I don't know what the locale-aware formatting does with it. Putting all these together it would not surprise me if it is unsuitable for sorting, and/or for converting back (accurately) to a datetime/comparing. Whereas thebirthTime()
you use for your extra column is indeed a datetime type and is suitable.Hence, as both I and @Christian-Ehrlicher have said, I would use
lastModified()
just as you usebirthDate()
for this column in your own code fordata()
method.