Qt之QHeaderView自定义排序(QSortFilterProxyModel)

来源:互联网 发布:上海企业网站排名优化 编辑:程序博客网 时间:2024/05/16 11:30

简述

对以上节的排序,我们衍伸了两点:

  1. 把一个字符串前面的数据按照字符串比较,而后面的数据按照整形比较。
  2. 将整形显示为字符串,而排序依然正常呢。

为了分别描述,这里我们先解决问题1。

  • 简述
  • 效果
  • 处理大小显示
  • QAbstractTableModel
  • QSortFilterProxyModel
  • 提示

效果

这里写图片描述

处理大小显示

// 定义GB、MB、KB的计算常量const int GB = 1024 * 1024 * 1024;const int MB = 1024 * 1024;const int KB = 1024;QString bytesToGBMBKB(qint64 size){    if (size / GB >= 1)        return QString("%1 GB").arg(QString::number(size / (float)GB, 'f', 2));    else if (size / MB >= 1)        return QString("%1 MB").arg(QString::number(size / (float)MB, 'f', 2));    else if (size / KB >= 1)        return QString("%1 KB").arg(QString::number(size / (float)KB, 'f', 2));    else        return QString("%1 Bytes").arg(size);}

QAbstractTableModel

这里只修改了一行代码,其它代码和上节相同。

// 表格项数据QVariant TableModel::data(const QModelIndex &index, int role) const{    if (!index.isValid())        return QVariant();    int nRow = index.row();    int nColumn = index.column();    FileRecord record = m_recordList.at(nRow);    switch (role)    {    case Qt::TextColorRole:        return QColor(Qt::white);    case Qt::TextAlignmentRole:        return QVariant(Qt::AlignLeft | Qt::AlignVCenter);    case Qt::DisplayRole:    {        if (nColumn == FILE_NAME_COLUMN)        {            return record.strFileName;        }        else if (nColumn == DATE_TIME_COLUMN)        {            return record.dateTime;        }        else if (nColumn == FILE_SIZE_COLUMN)        {            // 之前返回的qint64,现在转换为字符串            return bytesToGBMBKB(record.nSize);        }        return "";    }    default:        return QVariant();    }    return QVariant();}

QSortFilterProxyModel

QSortFilterProxyModel是用来排序和过滤的,不能单独使用,它只是一个“代理”,真正的数据需要QAbstractTableModel提供,可以重写lessThan来实现自己的排序算法。

SortFilterProxyModel::SortFilterProxyModel(QWidget *parent)    : QSortFilterProxyModel(parent){}SortFilterProxyModel::~SortFilterProxyModel(){}bool SortFilterProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const{    if (!source_left.isValid() || !source_right.isValid())        return false;    if ((source_left.column() == FILE_NAME_COLUMN) && (source_right.column() == FILE_NAME_COLUMN))    {        QVariant leftData = sourceModel()->data(source_left);        QVariant rightData = sourceModel()->data(source_right);        if (leftData.canConvert<QString>() && rightData.canConvert<QString>())        {            QString strLeft = leftData.toString();            QString strRight = rightData.toString();            // 去掉后缀.cpp            if (strLeft.contains("."))            {                int nIndex = strLeft.lastIndexOf(".");                strLeft = strLeft.left(nIndex);            }            if (strRight.contains("."))            {                int nIndex = strRight.lastIndexOf(".");                strRight = strRight.left(nIndex);            }            // 比较大小,如果字符串相同,则比较后面的整形数据            QStringList strLeftList = strLeft.split(" ");            QStringList strRightList = strRight.split(" ");            if ((strLeftList.count() >= 2) && (strRightList.count() >= 2))            {                int nResult = QString::compare(strLeftList.at(0), strRightList.at(0), Qt::CaseInsensitive);                if (nResult == 0)                {                    return strLeftList.at(1).toInt() < strRightList.at(1).toInt();                }                else                {                    return nResult;                }            }        }    }    return QSortFilterProxyModel::lessThan(source_left, source_right);}

提示

效果图中,只针对名称自定义排序了,大小只进行了转换,还尚未排序,因为存在多种解决方案,下节我会将方案一一列出,然后进行对比。

2 0
原创粉丝点击