Я хочу отсортировать таблицу по датам. Проблема в том, что они интерпретируются как строки, поэтому мой локальный формат даты отсортирован неправильно, например 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
по крайней мере, я могу сортировать по другим столбцам правильно.
Что я здесь не так делаю? Должен ли я реализовать другую функцию или что-нибудь? Я искал в интернете, но все, что я нашел, было проблемы с сортировкой целых чисел много лет назад, никогда не встречается 🙁
Я идиот (факт!)
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!
}
Я хочу поблагодарить вас за ваши добрые и быстрые ответы, но на этот раз проблема между стулом и клавиатурой существовала.
Согласно документации QSortFilterProxyModel, вы можете предоставить собственную реализацию lessThan (). http://doc.qt.io/qt-5/qsortfilterproxymodel.html#lessThan
Если по какой-либо причине это не работает должным образом, вы всегда можете отсортировать даты в виде строк, если вы форматируете эти даты, используя ISO8601 (ГГГГ-ММ-ДД). Именно так я обычно выбираю хранение (и последующую сортировку) дат при работе с базами данных.
Я думаю, что вы должны использовать 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
уже перегружен оператор <
,