В моем проекте модель отображается в виде дерева. Я использовал QSortFilterProxyModel для сортировки модели на основе идентификатора, установленного в Qt :: UserRole + 1. Это делит мой список на «тип» (как вы можете сказать по используемым значкам):
Однако я также хочу, чтобы каждый «тип» сортировался по алфавиту. Сначала я пытался сортировать вещи по алфавиту ПЕРВЫЙ, а затем сортировать их по типу, чтобы посмотреть, не переставит ли это вещи для правильной работы, но это не изменилось. Можно ли как-то сказать моей программе сортировать по двум ролям сортировки И определить, какая из них «идет первой?»
proxy->setSortRole(Qt::DisplayRole);
proxy->setSortRole(Qt::UserRole+1);
Так как мои дублированные URL были обнулены, вот рабочий пример прямо с официального примера после небольшой корректировки:
class MySortFilterProxyModel Q_DECL_FINAL : public QSortFilterProxyModel
{
Q_OBJECT
public:
MySortFilterProxyModel(QObject *parent)
: QSortFilterProxyModel(parent)
{
}
protected:
bool lessThan(const QModelIndex &left, const QModelIndex &right) const Q_DECL_OVERRIDE
{
QVariant leftData = sourceModel()->data(left);
QVariant rightData = sourceModel()->data(right);
// Do custom logic in here, e.g.:
return QString::localeAwareCompare(leftData.toString(), rightData.toString()) < 0;
}
};
Затем этот пользовательский класс будет обычно использоваться вместо оригинала в качестве замены. Вот и все!
Все, что мне нужно было сделать, это создать модель прокси другой модели прокси. Первый прокси упорядочил все по алфавиту, второй прокси упорядочил первый прокси по UserRole + 1.
QSortFilterProxyModel* proxy = new QSortFilterProxyModel(ui->treeNBT);
proxy->setSourceModel(model);
proxy->setDynamicSortFilter(false);
proxy->sort(0, Qt::AscendingOrder);
proxy->setSortCaseSensitivity(Qt::CaseInsensitive);
proxy->setSortRole(Qt::DisplayRole);
QSortFilterProxyModel* proxy2 = new QSortFilterProxyModel(ui->treeNBT);
proxy2->setSourceModel(proxy);
proxy2->setDynamicSortFilter(false);
proxy2->sort(0, Qt::AscendingOrder);
proxy2->setSortRole(Qt::UserRole+1);
ui->treeNBT->setModel(proxy2);
Гораздо проще, чем писать собственную логику сортировки в переопределенном классе. Заметного снижения производительности нет, так что это то, что я использую.
Изменить: изменил мой ответ … оглядываясь на мои старые вопросы, и это не лучший способ сделать это. Реализация класса была лучшим (и очевидным) способом. упс.
Вы должны создать подкласс прокси и реализовать свой собственный lessThan()
.
QSortFilterProxyModel использует виртуальный lessThan
метод определения порядка между модельными индексами. Только реализация по умолчанию lessThan
уважает роль, установленную setSortRole
, Вы можете переопределить его, чтобы обеспечить настраиваемое поведение сортировки, в этом случае setSortRole
устарел.
В официальной документации есть раздел по пользовательской сортировке вместе с примером кода: http://doc.qt.io/qt-5/qsortfilterproxymodel.html#details