1
votes

According to the Qt docs for QSortFilterProxyModel::lessThan():

bool QSortFilterProxyModel::lessThan(const QModelIndex & left, const QModelIndex & right) const [virtual protected]

Returns true if the value of the item referred to by the given index left is less than the value of the item referred to by the given index right, otherwise returns false.

This function is used as the < operator when sorting, and handles the following QVariant types:

[... snip built-in types ...]

Any other type will be converted to a QString using QVariant::toString().

And the docs for QVariant::toString() say:

QString QVariant::toString() const

Returns the variant as a QString if the variant has type() String, Bool, ByteArray, Char, Date, DateTime, Double, Int, LongLong, StringList, Time, UInt, or ULongLong; otherwise returns an empty string.

I have a user-defined struct:

struct foo {
    ...
};

inline bool operator <(const foo& a, const foo& b) { 
    ...
};

Q_DECLARE_METATYPE(foo)

I can make QVariants from this:

QVariant r; 
r.setValue(foo());
return r;

However, if I return such a QVariant for the sorting role then, based on the docs above it won't work - it'll just end up sorting on empty strings.

It seems like what I have to do, to preserve the same order as the operator < I defined for foo, is come up with a string representation for foo which ends up having the exact same sort order.

This is really unappealing. It's clunky and involves code duplication. Is there any other way?

1

1 Answers

1
votes

I believe what I have to do is subclass the QSortFilterProxyModel and overload lessThan to do something like return sourceModel()->data(left).value<foo>() < sourceModel()->data(right).value<foo>();