Qt之QTableView添加复选框(QAbstractItemDelegate)

来源:互联网 发布:老巴黎西洋家具淘宝网 编辑:程序博客网 时间:2024/04/30 05:59

简述

上节分享了使用自定义模型QAbstractTableModel来实现复选框。下面我们来介绍另外一种方式:
自定义委托-QAbstractItemDelegate。

  • 简述
  • 效果
  • QAbstractTableModel
    • 源码
    • 接口说明
  • QStyledItemDelegate
    • 源码
    • 接口说明
  • 样式
  • 使用

效果

这里写图片描述

QAbstractTableModel

源码

table_model.cpp

#define CHECK_BOX_COLUMN 0#define File_PATH_COLUMN 1TableModel::TableModel(QObject *parent)    : QAbstractTableModel(parent){}TableModel::~TableModel(){}// 更新表格数据void TableModel::updateData(QList<FileRecord> recordList){    m_recordList = recordList;    beginResetModel();    endResetModel();}// 行数int TableModel::rowCount(const QModelIndex &parent) const{    return m_recordList.count();}// 列数int TableModel::columnCount(const QModelIndex &parent) const{    return 2;}// 设置表格项数据bool TableModel::setData(const QModelIndex &index, const QVariant &value, int role){    if (!index.isValid())        return false;    int nColumn = index.column();    FileRecord record = m_recordList.at(index.row());    switch (role)    {    case Qt::DisplayRole:    {        if (nColumn == File_PATH_COLUMN)        {            record.strFilePath = value.toString();            m_recordList.replace(index.row(), record);            emit dataChanged(index, index);            return true;        }    }    case Qt::CheckStateRole:    case Qt::UserRole:    {        if (nColumn == CHECK_BOX_COLUMN)        {            record.bChecked = value.toBool();            m_recordList.replace(index.row(), record);            emit dataChanged(index, index);            return true;        }    }    default:        return false;    }    return false;}// 表格项数据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_PATH_COLUMN)            return record.strFilePath;        return "";    }    case Qt::UserRole:    {        if (nColumn == CHECK_BOX_COLUMN)            return record.bChecked;    }    default:        return QVariant();    }    return QVariant();}// 表头数据QVariant TableModel::headerData(int section, Qt::Orientation orientation, int role) const{    switch (role)    {    case Qt::TextAlignmentRole:        return QVariant(Qt::AlignLeft | Qt::AlignVCenter);    case Qt::DisplayRole:    {        if (orientation == Qt::Horizontal)        {            if (section == CHECK_BOX_COLUMN)                return QStringLiteral("状态");            if (section == File_PATH_COLUMN)                return QStringLiteral("文件路径");        }    }    default:        return QVariant();    }    return QVariant();}// 表格可选中、可复选Qt::ItemFlags TableModel::flags(const QModelIndex &index) const{    if (!index.isValid())        return QAbstractItemModel::flags(index);    Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;    return flags;}

接口说明

  • updateData
    主要用于更新数据,刷新界面。

  • data
    用来显示数据,根据角色(颜色、文本、对齐方式、选中状态等)判断需要显示的内容。

  • setData
    用来设置数据,根据角色(颜色、文本、对齐方式、选中状态等)判断需要设置的内容。

  • headerData
    用来显示水平/垂直表头的数据。

  • flags
    用来设置单元格的标志(可用、可选中、可复选等)。

QStyledItemDelegate

源码

CheckBoxDelegate::CheckBoxDelegate(QObject *parent)    : QStyledItemDelegate(parent){}CheckBoxDelegate::~CheckBoxDelegate(){}// 绘制复选框void CheckBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const{    QStyleOptionViewItem viewOption(option);    initStyleOption(&viewOption, index);    if (option.state.testFlag(QStyle::State_HasFocus))        viewOption.state = viewOption.state ^ QStyle::State_HasFocus;    QStyledItemDelegate::paint(painter, viewOption, index);    if (index.column() == CHECK_BOX_COLUMN)    {        bool data = index.model()->data(index, Qt::UserRole).toBool();        QStyleOptionButton checkBoxStyle;        checkBoxStyle.state = data ? QStyle::State_On : QStyle::State_Off;        checkBoxStyle.state |= QStyle::State_Enabled;        checkBoxStyle.iconSize = QSize(20, 20);        checkBoxStyle.rect = option.rect;        QCheckBox checkBox;        QApplication::style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &checkBoxStyle, painter, &checkBox);    }}// 响应鼠标事件,更新数据bool CheckBoxDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index){    QRect decorationRect = option.rect;    QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);    if (event->type() == QEvent::MouseButtonPress && decorationRect.contains(mouseEvent->pos()))    {        if (index.column() == CHECK_BOX_COLUMN)        {            bool data = model->data(index, Qt::UserRole).toBool();            model->setData(index, !data, Qt::UserRole);        }    }    return QStyledItemDelegate::editorEvent(event, model, option, index);}

接口说明

  • paint
    用来设置表格样式,绘制复选框-状态、大小、显示区域等。

  • editorEvent
    用来设置数据,响应鼠标事件,判断当前选中状态,互相切换。

样式

复选框样式:

QCheckBox{        spacing: 5px;        color: white;}QCheckBox::indicator {        width: 17px;        height: 17px;}QCheckBox::indicator:enabled:unchecked {        image: url(:/Images/checkBox);}QCheckBox::indicator:enabled:unchecked:hover {        image: url(:/Images/checkBoxHover);}QCheckBox::indicator:enabled:unchecked:pressed {        image: url(:/Images/checkBoxPressed);}QCheckBox::indicator:enabled:checked {        image: url(:/Images/checkBoxChecked);}QCheckBox::indicator:enabled:checked:hover {        image: url(:/Images/checkBoxCheckedHover);}QCheckBox::indicator:enabled:checked:pressed {        image: url(:/Images/checkBoxCheckedPressed);}QCheckBox::indicator:enabled:indeterminate {        image: url(:/Images/checkBoxIndeterminate);}QCheckBox::indicator:enabled:indeterminate:hover {        image: url(:/Images/checkBoxIndeterminateHover);}QCheckBox::indicator:enabled:indeterminate:pressed {        image: url(:/Images/checkBoxIndeterminatePressed);}

使用

QTableView *pTableView = new QTableView(this);TableModel *pModel = new TableModel(this);CheckBoxDelegate *pDelegate = new CheckBoxDelegate(this);// 设置单行选中、最后一列拉伸、表头不高亮、无边框等pTableView->setSelectionBehavior(QAbstractItemView::SelectRows);pTableView->horizontalHeader()->setStretchLastSection(true);pTableView->horizontalHeader()->setHighlightSections(false);pTableView->verticalHeader()->setVisible(false);pTableView->setShowGrid(false);pTableView->setFrameShape(QFrame::NoFrame);pTableView->setSelectionMode(QAbstractItemView::SingleSelection);pTableView->setModel(pModel);pTableView->setItemDelegate(pDelegate);// 加载数据、更新界面QList<FileRecord> recordList;for (int i = 0; i < 5; ++i){    FileRecord record;    record.bChecked = false;    record.strFilePath = QString("E:/Qt/image_%1.png").arg(i + 1);    recordList.append(record);}pModel->updateData(recordList);
5 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 洗手盆裂缝漏水怎么办 洗手盆堵了怎么办 征信账号注册怎么办 注册不了征信号怎么办 阿里巴巴一键铺货到淘宝发货怎么办 淘宝购物的问题怎么办 买家评价被删除怎么办 淘宝订单虚假交易怎么办 被判定虚假物流怎么办 淘宝有虚假交易怎么办 微信辅助不了怎么办 微信验证失败怎么办 淘宝占空间太大怎么办 淘宝占用空间大怎么办 ipad空间不够用怎么办 ipadmini密码忘了怎么办 旧ipad特别卡怎么办 苹果ipad反应慢怎么办 手机垃圾多了怎么办 ipad2内存过低怎么办 苹果平板ipad内存不足怎么办 手机dns配置错误怎么办 蓝牙已停止运行怎么办 ipad看电视闪退怎么办 ipad为什么看电视会闪退怎么办 微淘直播延迟怎么办 手机淘宝进群领金币怎么办 做淘客冲销量停止淘客后怎么办 微信中零钱提现怎么办 淘宝买家不签收怎么办 小龙虾没人下单怎么办 淘宝直播不浮现怎么办 淘宝直播看不了怎么办 理财客户说没钱怎么办 投资不给钱了怎么办 工作中遇到挫折怎么办 手机qq出现异常怎么办 农行卡出现异常怎么办 淘宝长期不发货怎么办 快递一直不发货怎么办 申请退款被拒绝怎么办