使用QAbstractTableModel实现点击某一行首列单元格全选后面

前沿

工作中遇到一种问题:需要一种表格,第一例单元格为全选CheckBox,点击这个CheckBox,勾选一行之后的单元格。
整体效果如下图:

首列全选效果图

实现描述

  1. 直接继承QAstractTableViewModel,主要重写6个关键性的虚函数:
虚函数函数描述
headerData(int section, Qt::Orientation orientation, int role)根据role属性返回内部调用者横竖表头单元格的一些属性:字体、文本、颜色、居中等
int rowCount(const QModelIndex& parent)告诉内部调用者表格行数,一般为容器成员变量count
int columnCount(const QModelIndex &parent告诉内部调用者表格列数,一般为表头字段数
QVariant data(const QModelIndex &index, int role)根据role返回内部调用者每个单元格的属性数据QVariant
bool setData(const QModelIndex &index, const QVariant &value, int role)界面数据发生修改,内部调用者调用该接口会根据role重新设置每个单元格的属性数据
Qt::ItemFlags flags(const QModelIndex &index)告诉调用者该单元格的使能、可选择性、可勾选等标志
QVariant MultiCheckModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    // FIXME: Implement me!
    QVariant retVal;
    switch (role) {
    case Qt::TextAlignmentRole:
    {
        retVal = QVariant(Qt::AlignLeft | Qt::AlignHCenter);
        break;
    }
    case Qt::DisplayRole:
    {
        if (orientation == Qt::Horizontal)
        {
            if(section == static_cast<int>(HeaderCheckItem::Col_SelectAll))
            {
                retVal = tr("Select All");
            }
            if(section == static_cast<int>(HeaderCheckItem::Col_ItemMax))
            {
                retVal = tr("Max");
            }
            if(section == static_cast<int>(HeaderCheckItem::Col_ItemAvg))
            {
                retVal = tr("Avg");
            }
            if(section == static_cast<int>(HeaderCheckItem::Col_ItemMin))
            {
                retVal = tr("Min");
            }
        }
        break;
    }
    default:
        break;
    }
    return retVal;
}
int MultiCheckModel::rowCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;

    // FIXME: Implement me!
    return m_listData.count();
}
int MultiCheckModel::columnCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;

    // FIXME: Implement me!
    return static_cast<int>(HeaderCheckItem::Col_Total);
}
QVariant MultiCheckModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    // FIXME: Implement me!
    QVariant retVal;

    int nRow = index.row();
    int nColumn = index.column();
    const ModelItem& itemChooseState = m_listData.at(nRow);

    switch (role) {
    case Qt::CheckStateRole:
    {
        bool bState = false;
        if(nColumn == static_cast<int>(HeaderCheckItem::Col_SelectAll))
        {
            bState = itemChooseState.bShowmin && itemChooseState.bShowavg && itemChooseState.bShowmax;
        }
        if(nColumn == static_cast<int>(HeaderCheckItem::Col_ItemMax))
        {
            bState = itemChooseState.bShowmax;
        }
        if(nColumn == static_cast<int>(HeaderCheckItem::Col_ItemAvg))
        {
            bState = itemChooseState.bShowavg;
        }
        if(nColumn == static_cast<int>(HeaderCheckItem::Col_ItemMin))
        {
            bState = itemChooseState.bShowmin;
        }

        retVal = bState ? Qt::Checked : Qt::Unchecked;
    }
    }
    return retVal;
}
bool MultiCheckModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (!index.isValid())
        return false;

    // FIXME: Implement me!
    QVariant retVal;
    int nColumn = index.column();
    ModelItem& item = m_listData[index.row()];
    switch (role) {
    case Qt::CheckStateRole:
    {
        if(nColumn == static_cast<int>(HeaderCheckItem::Col_SelectAll))
        {
            item.bShowmin = item.bShowavg = item.bShowmax = (value.toInt() == Qt::Checked);
            emit dataChanged(index, index);
            return true;
        }
        if(nColumn == static_cast<int>(HeaderCheckItem::Col_ItemMax))
        {
            item.bShowmax = (value.toInt() == Qt::Checked);
            emit dataChanged(index, index);
            return true;
        }
        if(nColumn == static_cast<int>(HeaderCheckItem::Col_ItemAvg))
        {
            item.bShowavg = (value.toInt() == Qt::Checked);
            emit dataChanged(index, index);
            return true;
        }
        if(nColumn == static_cast<int>(HeaderCheckItem::Col_ItemMin))
        {
            item.bShowmin = (value.toInt() == Qt::Checked);
            emit dataChanged(index, index);
            return true;
        }
        break;
    }
    }

    return false;
}
Qt::ItemFlags MultiCheckModel::flags(const QModelIndex &index) const
{
    if(!index.isValid())
    {
        return QAbstractItemModel::flags(index);
    }

    Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
    int nColumn = index.column();
    if(nColumn == static_cast<int>(HeaderCheckItem::Col_SelectAll)
            || nColumn == static_cast<int>(HeaderCheckItem::Col_ItemMax)
            || nColumn == static_cast<int>(HeaderCheckItem::Col_ItemAvg)
            || nColumn == static_cast<int>(HeaderCheckItem::Col_ItemMin))
    {
        flags |= Qt::ItemIsUserCheckable;
    }

    return flags;
}
  1. 编写一个设置接口setShowData,将上层数据传递到QAstractTableViewModel中
    beginResetModel()endResetModel() 用来通知表格重绘刷新
void MultiCheckModel::setShowData(const QList<MultiCheckModel::ModelItem> &list)
{
    m_listData = list;

    // 刷新列表数据
    beginResetModel();
    endResetModel();
}
  1. 界面勾选发生改变时,连接dataChanged信号,槽函数继续调用 beginResetModel()endResetModel() 用来通知表格重绘刷新
void MultiCheckModel::initConnect()
{
    connect(this, &QAbstractItemModel::dataChanged, [=]
    {
        // 刷新列表数据
        beginResetModel();
        endResetModel();
    });
}

代码的话之后上传GitHub,下次修改时,上传url

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值