Qt之QHeaderView自定义排序(QSortFilterProxyModel)

简介: 简述对以上节的排序,我们衍伸了两点:把一个字符串前面的数据按照字符串比较,而后面的数据按照整形比较。将整形显示为字符串,而排序依然正常呢。为了分别描述,这里我们先解决问题1。简述效果处理大小显示QAbstractTableModelQSortFilterProxyModel提示效果处理大小显示// 定义GB

简述

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

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

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

效果

这里写图片描述

处理大小显示

// 定义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);
}

提示

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

目录
相关文章
|
7月前
|
存储 机器学习/深度学习 人工智能
Qt魔法书:打造自定义鼠标键盘脚本(二)
Qt魔法书:打造自定义鼠标键盘脚本
220 0
|
2月前
(8)Qt中的自定义信号
本文介绍了如何在Qt框架中创建和使用自定义信号,并通过一个父子窗口切换的示例来展示自定义信号的实现和应用。
90 3
(8)Qt中的自定义信号
|
2月前
(7)Qt中的自定义槽(函数)
这篇文章介绍了在Qt中如何定义和使用自定义槽函数,包括类成员函数、静态类成员函数、全局函数和lambda表达式作为槽函数的示例,以及使用lambda表达式时的注意事项。
60 2
(7)Qt中的自定义槽(函数)
|
4月前
|
搜索推荐 C++
【Qt 学习笔记】Qt窗口 | 对话框 | 创建自定义对话框
【Qt 学习笔记】Qt窗口 | 对话框 | 创建自定义对话框
104 4
|
4月前
【qt】自定义对话框(2)
【qt】自定义对话框(2)
31 0
|
4月前
【qt】自定义对话框(1)
【qt】自定义对话框(1)
36 0
|
5月前
|
C++
Qt中的信号与槽如何学习?(包括自定义信号)这篇文章告诉你
以现实中的事件来举例的话,例如有两把不同颜色的信号枪,分别是红色,绿色,打响不通颜色的信号枪会触发不同的槽发生,比如说打响红色这个人就跑步,绿色就走步,但是还有一个很重要的机制,那就是连接,我们需要把信号枪去跟这个人的动作连接起来。 如果上面理解没问题的话我们可以把信号和槽看成两个工具,我们最重要的是如何去把这两个工具连接起来。 它的作用可以让我们更加灵活的去使用不同窗口间的切换以及某些事件的连接。
107 0
|
7月前
|
C++
【qt】自定义代理类
【qt】自定义代理类
70 0
|
7月前
|
搜索推荐
【qt】自定义界面类
【qt】自定义界面类
64 0
|
7月前
|
开发框架 Linux API
Qt魔法书:打造自定义鼠标键盘脚本(一)
Qt魔法书:打造自定义鼠标键盘脚本
83 0