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委托并居中显示,需要以下步骤:
- 创建一个自定义的委托类,继承自QStyledItemDelegate。
- 重写该委托类的paint函数,实现QCheckBox的居中显示。
- 重写该委托类的editorEvent函数,实现QCheckBox的状态改变。
- 为QTableView的相应单元格设置该委托类。
- 在数据模型中处理QCheckBox状态的更改,以便在重绘时正确显示。
4.1 第一步
和前几篇文章一样,我们需要建立一个项目,并且需要我们拖拽QTableView,以及对其初始化。我们在这里就不在赘述,大家可以参考前面几篇文章是如何创建的。
4.2 第二步
- 创建Delegate类,方法和前面几篇文章一样
- 需要我们先定义三函数
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 第三步
- 实现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);
}
}
- 实现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 效果图
文章来源:https://www.toymoban.com/news/detail-490994.html
5 源码
源码文章来源地址https://www.toymoban.com/news/detail-490994.html
到了这里,关于QT中级(3)QTableView自定义委托(三)实现QCheckBox委托并且将QCheckBox居中的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!