QT中级(3)QTableView自定义委托(三)实现QCheckBox委托并且将QCheckBox居中

1 写在前面的话

我们在之前写的《QT(7)-初识委托》文章末尾提到,“使用一个类继承QStyledItemDelegate实现常用的控件委托,在使用时可以直接调用接口,灵活实现各种委托”。我们接下来几篇文章将先详细讲解各个控件的委托,最后整理成一个类,并分享源码。如果大家感兴趣,可以点个关注,后面我们一起学习!

讲解比较详细,大家可以跟着一步一步做,自己就可以实现了。

2 需要用到的部分知识

《QT(3)-QTableView》
《QT(4)-QAbstractItemView》
《QT(6)-QStandardItemModel》
《QT(7)-初识委托》

3 同系列文章

QT中级(1)QTableView自定义委托(一)实现QSpinBox、QDoubleSpinBox委托
QT中级(2)QTableView自定义委托(二)实现QProgressBar委托

4 实现QCheckBox委托

在QTableView中实现QCheckBox委托并居中显示,需要以下步骤:

  1. 创建一个自定义的委托类,继承自QStyledItemDelegate。
  2. 重写该委托类的paint函数,实现QCheckBox的居中显示。
  3. 重写该委托类的editorEvent函数,实现QCheckBox的状态改变。
  4. 为QTableView的相应单元格设置该委托类。
  5. 在数据模型中处理QCheckBox状态的更改,以便在重绘时正确显示。

4.1 第一步

和前几篇文章一样,我们需要建立一个项目,并且需要我们拖拽QTableView,以及对其初始化。我们在这里就不在赘述,大家可以参考前面几篇文章是如何创建的。

4.2 第二步

  1. 创建Delegate类,方法和前面几篇文章一样
  2. 需要我们先定义三函数
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override;

这三个函数的含义前面几篇文章都已经提到了,不再赘述。

4.3 第三步

  1. 实现paint函数
void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{

    if(index.column() == 2)
    {
        bool value = index.data(Qt::UserRole).toInt();
        QStyleOptionButton checkBoxOption;
        QRect checkBoxRect = QApplication::style()->subElementRect(QStyle::SE_CheckBoxIndicator, &checkBoxOption);
        checkBoxOption.rect = option.rect;
        checkBoxOption.rect.setLeft(option.rect.left() + (option.rect.width() - checkBoxRect.width()) / 2);
        checkBoxOption.rect.setTop(option.rect.top() + (option.rect.height() - checkBoxRect.height()) / 2);
        checkBoxOption.state = value ? QStyle::State_On :QStyle::State_Off;
        checkBoxOption.state |= QStyle::State_Enabled;
        QApplication::style()->drawControl(QStyle::CE_CheckBox, &checkBoxOption, painter);
    }//if
    else
    {
        QStyledItemDelegate::paint(painter,option,index);
    }
}
  1. 实现editorEvent函数
bool Delegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    if(event->type() == QEvent::MouseButtonDblClick)//禁止双击编辑
        return true;
    //过滤鼠标松开
    if (event->type() == QEvent::MouseButtonRelease) {
        return false;
    }

    bool checked = index.data(Qt::UserRole).toBool();
    model->setData(index, !checked, Qt::UserRole);

    return QStyledItemDelegate::editorEvent(event,model,option,index);
}

4.4 最后一步

我们需要在mainwindow.cpp中的init()调用delegate类实现委托。我们将QTableView的第一列设置为委托:

更新mainwindow.cpp中的init()函数

void MainWindow::init()
{
    QStringList columnNames;
    columnNames<<"QSpinBox"<<"QComboBox"<<"QCheckBox"<<"QProgressBar"<<"···";

    model = new QStandardItemModel;
    model->setRowCount(10);
    model->setHorizontalHeaderLabels(columnNames);
    ui->tableView->setModel(model);

    Delegate *checkDelegate = new Delegate;
    ui->tableView->setItemDelegateForColumn(2,checkDelegate);
}

4.5 效果图

在这里插入图片描述

5 源码

源码

要在QTableView中添加复选框,可以使用QAbstractItemDelegate。下面是一个简单的示例: 首先,我们需要创建一个自定义委托类,继承自QItemDelegate: ```cpp class CheckBoxDelegate : public QItemDelegate { public: CheckBoxDelegate(QObject *parent = nullptr) : QItemDelegate(parent) {} QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override { QCheckBox *editor = new QCheckBox(parent); editor->setStyleSheet("margin-left:50%;margin-right:50%;"); return editor; } void setEditorData(QWidget *editor, const QModelIndex &index) const override { bool value = index.model()->data(index, Qt::EditRole).toBool(); QCheckBox *checkBox = static_cast<QCheckBox*>(editor); checkBox->setChecked(value); } void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override { QCheckBox *checkBox = static_cast<QCheckBox*>(editor); model->setData(index, checkBox->isChecked(), Qt::EditRole); } void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override { editor->setGeometry(option.rect); } }; ``` 这个类中主要实现了四个函数: - createEditor:创建一个QCheckBox作为编辑器,并将其居中显示 - setEditorData:将模型中的数据设置到编辑器中 - setModelData:将编辑器中的数据设置回模型中 - updateEditorGeometry:更新编辑器的位置和大小 接下来,在使用QTableView的地方,创建一个QStandardItemModel,并为需要添加复选框的列设置该自定义委托类即可: ```cpp QStandardItemModel *model = new QStandardItemModel(); model->setColumnCount(2); model->setRowCount(3); for (int row = 0; row < model->rowCount(); ++row) { for (int col = 0; col < model->columnCount(); ++col) { QModelIndex index = model->index(row, col, QModelIndex()); model->setData(index, QVariant(QString("row %1, column %2").arg(row).arg(col))); } } ui->tableView->setModel(model); ui->tableView->setItemDelegateForColumn(1, new CheckBoxDelegate(ui->tableView)); ``` 在这个示例中,我们将第二列设置为复选框列,所以我们使用setItemDelegateForColumn函数将该自定义委托类设置给第二列。然后,我们将该模型设置到QTableView中。完成以上步骤后,运行程序,即可看到复选框列已经添加到了QTableView中。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m晴朗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值