QSortFilterProxyModel сортировать по дате

Я хочу отсортировать таблицу по датам. Проблема в том, что они интерпретируются как строки, поэтому мой локальный формат даты отсортирован неправильно, например 26. September больше чем 16. November, так как 26 > 16,

Во всяком случае, поэтому я настроил свою собственную модель и попробовал это так:

QVariant MyModel::data(const QModelIndex &index, int role) const
{
if(role == Qt::UserRole)
{
if(index.column() == 5) // Date
return QSqlTableModel::data(index, role).toDate();
}

if(role == Qt::DisplayRole)
{
if(index.column() == 5) // Date
return QSqlTableModel::data(index.role).toDate().toString("dd MMMM yyyy");
}
}

и я установил sortRole как это:

proxyModel->setSortRole(Qt::UserRole);

Соответствующие строки на самом деле вызывают, но теперь я не могу отсортировать таблицу вообще. Это просто не отвечает. Стрелки (представляющие порядок asc или desc) в соответствующих столбцах изменяются, но данные — нет.
Конечно, я установил остальные как:

proxyModel->setDynamicSortFilter(true);
proxyModel->setSourceModel(myDBModel);
proxyModel->setFilterKeyColumn(1);
proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);

Если я не установлю sortRole по крайней мере, я могу сортировать по другим столбцам правильно.
Что я здесь не так делаю? Должен ли я реализовать другую функцию или что-нибудь? Я искал в интернете, но все, что я нашел, было проблемы с сортировкой целых чисел много лет назад, никогда не встречается 🙁

0

Решение

Я идиот (факт!)

Qt уже предоставил все, что мне было нужно, это была просто глупая ошибка с моей стороны. На самом деле две вещи:

   if(role == Qt::UserRole)
{
if(index.column() == 5)
return QDate::fromString(QSqlTableModel::data(index, Qt::DisplayRole).toString(), "yyyy-MM-dd"); // 1st Mistake, no correct conversion. I always got QVariant(invalid)
// 1.1 Mistake, also, grab the data from Qt::DisplayRole, not from Qt::UserRole!

return QSqlTableModel::data(index, Qt::DisplayRole); // 2nd Mistake. Because I didn't add that line I couldn't sort it on any other column anymore. When I finally could sort it on the dates I couldn't on the other columns, then I thought about adding this line et voila!
}

Я хочу поблагодарить вас за ваши добрые и быстрые ответы, но на этот раз проблема между стулом и клавиатурой существовала.

2

Другие решения

Согласно документации QSortFilterProxyModel, вы можете предоставить собственную реализацию lessThan (). http://doc.qt.io/qt-5/qsortfilterproxymodel.html#lessThan

Если по какой-либо причине это не работает должным образом, вы всегда можете отсортировать даты в виде строк, если вы форматируете эти даты, используя ISO8601 (ГГГГ-ММ-ДД). Именно так я обычно выбираю хранение (и последующую сортировку) дат при работе с базами данных.

1

Я думаю, что вы должны использовать Custom Sort / Filter Model. Вы должны «научить» класс, как его сравнивать. Посмотрите на этот пример: http://doc.qt.io/qt-5/qtwidgets-itemviews-customsortfiltermodel-example.html

Я думаю, что самый полезный для вас код вы можете найти здесь:

bool MySortFilterProxyModel::lessThan(const QModelIndex &left,
const QModelIndex &right) const
{
QVariant leftData = sourceModel()->data(left);
QVariant rightData = sourceModel()->data(right);

if (leftData.type() == QVariant::DateTime)
return leftData.toDateTime() < rightData.toDateTime();
}

QDateTime уже перегружен оператор <,

1
По вопросам рекламы [email protected]