zoukankan      html  css  js  c++  java
  • Qt之QHeaderView自定义排序(QSortFilterProxyModel)

    简述

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

    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);
    }

    提示

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

  • 相关阅读:
    没有内存,怎么还能跑程序呢
    风物长宜放眼量,人间正道是沧桑
    一篇文章带你「重新认识」线程上下文切换怎么玩儿
    一文带你怼明白进程和线程通信原理
    万字长文带你还原进程和线程
    这些操作系统的概念,保你没听过!
    什么叫操作系统啊 | 战术后仰
    你要问我应用层?我就和你扯扯扯
    面试官问你MyBatis SQL是如何执行的?把这篇文章甩给他
    从这道字符串处理的难题,寻找解决复杂问题的套路
  • 原文地址:https://www.cnblogs.com/itrena/p/5938374.html
Copyright © 2011-2022 走看看