QSortFilterProxyModel按日期排序

时间:2014-10-26 16:00:29

标签: c++ qt sorting qt5 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,我可以正确排序其他列。 我在这做错了什么?我是否必须实施其他功能?我浏览了一下互联网,但我发现的只是几年前排序整数的问题,而不是日期:(

3 个答案:

答案 0 :(得分:2)

我是个白痴(事实上!)

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!
    }

我想感谢你的善意和快速的答案,但这次主席和键盘之间存在问题。

答案 1 :(得分:1)

我认为您应该使用自定义排序/过滤模型。你应该“教”课程如何比较它。看一下这个例子: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已经重载了运算符<

答案 2 :(得分:1)

根据QSortFilterProxyModel文档,您可以提供自己的lessThan()实现。 http://doc.qt.io/qt-5/qsortfilterproxymodel.html#lessThan

如果出于某种原因无法按预期工作,如果使用ISO8601(YYYY-MM-DD)格式化这些日期,则始终可以将日期排序为字符串。这就是我在处理数据库时通常选择存储(以及稍后排序)日期的方式。