一、设计float型spinbox代理类(定义int型spinbox和combox选项列表同此步骤)
1、新建对话框
选择new file -> C/C++ -> C++ class 创建
2、新建C++类对话框
类名称(class name)为新建的类的名称设置为TFloatSpinDelegate。Base class基类名称,选择自定义,输入QStyledItemDelegate。Header file Souce file根据class name自动生成。
勾选 include QObject 与 add Q_OBJECT,建议勾上无论是否使用元对象系统 。
二、重新实现createEditor() setEditorData() setModelData() updateEditorGeometry()四个函数
1、函数原型
1)createEditor():可创建用于编辑模型数据的界面组件,称为代理编辑器。
QWidget *QStyledItemDelegate::createEditor(
QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index
)
参数2:QStyleOptionViewItem 是 Qt 中用于描述视图项外观和行为的类,继承自QStyleOption
2)setEditorData():从数据模型获取项的某个角色,一般是EditRole角色的数据(EditRole为模型索引QModelIndex中Qt::ItemDataRole的枚举值,见Qt6 C++开发指南p175)
void QStyledItemDelegate::setEditorData(QWidget *editor,const QModelIndex &index)
Qt::ItemDataRole常用枚举值
枚举值 | 角色数据类型 | 含义 |
Qt::DisplayRole | QString | 界面上显示的字符串 |
Qt::DecorationRole | QIcon、QColor | 界面上的装饰 |
Qt::EditRole | QString | 界面上适合再编辑器中显示的数据 |
Qt::ToolTipRole | QString | 项的toolTip字符串 |
Qt::StatusTipRole | QString |
项的statusTip字符串 |
Qt::FontRole | QFont | 项的字体 |
Qt::TextAlignmentRole | Qt::Alignment | 项的对齐方式 |
Qt::BackgroundRole | QBrush | 项的背景色 |
Qt::ForegroundRole | QBrush | 项的前景色 |
Qt::CheckStateRole | Qt::CheckState | 项的复选状态 |
Qt::UserRole | QVariant | 自定义的项目数据 |
3)setModelData():完成对当前单元格的编辑。
void QStyledItemDelegate::setModelData(
QWidget *editor,
QAbstractItemModel *model,
const QModleIndex &index
)
参数2:QAbstractItemModel在Qt框架中中的一个核心抽象基类,在Qt的模型/视图架构中主要功能是为视图组件提供一个标准化的接口,使其能够访问和操作数据。
4)updateEditorGeometry():调用此函数时为组件设置合适大小。
void QStyledItemDelegate::updateEditorGeometry(
QWidget *editor,
const QStyleOptionViewItem &option,
const QModelIndex &index
)
2、.h定义,.cpp重新实现
1)浮点型spinbox代理器
tfloatspinboxdelegate.h
class TFloatSpinDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit TFloatSpinDelegate(QObject *parent=nullptr);
QWidget *createEditor(QWidget *parent,const QStyleOptionViewItem &option,const QModelIndex &index)const;
void setEditorData(QWidget *editor,const QModelIndex &index)const;
void setModelData(QWidget *editor,QAbstractItemModel *model,const QModelIndex &index)const;
void updateEidtorGeometry(QWidget *editor,const QStyleOptionViewItem &option,const QModelIndex &index)const;
};
tfloatspinboxdelegate.cpp文件
#include "tfloatspindelegate.h"
#include <QStyleOptionViewItem>
#include <QModelIndex>//头文件class声明,cpp文件引入
#include <QAbstractItemModel>
#include <QDoubleSpinBox>
TFloatSpinDelegate::TFloatSpinDelegate(QObject *parent): QStyledItemDelegate{parent} {}
QWidget *TFloatSpinDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
//创建代理编辑器
Q_UNUSED(option);
Q_UNUSED(index);
QDoubleSpinBox *editor=new QDoubleSpinBox(parent);
editor->setFrame(false);//设置无边框
editor->setMinimum(0);
editor->setMaximum(2000);
editor->setDecimals(2);//设置显示小数位
return editor;//返回创建的spinBox
}
void TFloatSpinDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
//QAbstractItemModel定义了函数data(),可以返回不同角色的数据
float value=index.model()->data(index,Qt::EditRole).toFloat();//EditRole界面上适合在编辑器中显示的数据,一般是文字
//设置为代理编辑器的值
QDoubleSpinBox *spinbox=static_cast<QDoubleSpinBox*>(editor);//比较自然和低风险的转换,但static_cast不能用于在不同类型的指针之间的转换
spinbox->setValue(value);
}
void TFloatSpinDelegate::setModelData(QWidget *editor,QAbstractItemModel *model, const QModelIndex &index) const
{
QDoubleSpinBox* spinbox=static_cast<QDoubleSpinBox*>(editor);
float value=spinbox->value();
QString str=QString::asprintf("%.2f",value);//后2位显示
model->setData(index,str,Qt::EditRole);//保存数据模型
}
void TFloatSpinDelegate::updateEidtorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
Q_UNUSED(index);
//QStyleOptionViewItem继承自QStyleOption,用于描述外观和行为的类
//通用方法:rect,size获取、设置选项的矩形区域大小
editor->setGeometry(option.rect);//设置组件大小
}
updateEditorGemometry()函数中QStyleOptionViewItem继承子QStyleOption,描述外观和行为的类,rect()为获取option矩形区域大小。
2)选项列表代理类设计
除重新重新实现四个函数外,令定义选项列表QStringList变量和bool变量,用来存放列表内容和是否可编辑状态,下面tcomboboxdelegate.h文件
private:
QStringList m_itemList;//选项列表
bool m_editable;
public:
explicit TComboBoxDelegate(QObject *parent = nullptr);
void setItems(QStringList items,bool editable);//初始化列表内容,是否可编辑
QWidget *createEditor(QWidget *parent,const QStyleOptionViewItem &option,const QModelIndex &index)const;
void setEditorData(QWidget *editor,const QModelIndex &index)const;
void setModelData(QWidget *editor,QAbstractItemModel *model,const QModelIndex &index)const;
void updateEditorGeometry(QWidget *editor,const QStyleOptionViewItem &option,const QModelIndex &index)const;
tcomboboxdelegate.cpp文件
void TComboBoxDelegate::setItems(QStringList items, bool editable)
{
m_itemList=items;
m_editable=editable;
}
QWidget *TComboBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
//初始化编辑器
Q_UNUSED(option);
Q_UNUSED(index);
QComboBox *editor=new QComboBox(parent);
editor->setEditable(m_editable);//设置是否可编辑
for(int i=0;i<m_itemList.count();i++)
editor->addItem(m_itemList.at(i));
return editor;
}
void TComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
//编辑器数据修改
QString str=index.model()->data(index,Qt::EditRole).toString();
QComboBox *combox=static_cast<QComboBox*>(editor);
combox->setCurrentText(str);//设置文本
}
void TComboBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
//将编辑器数据保存到模型
QComboBox* combox=static_cast<QComboBox*>(editor);
QString str=combox->currentText();
model->setData(index,str,Qt::EditRole);//设置模型数据
}
void TComboBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
Q_UNUSED(index);
editor->setGeometry(option.rect);
}
3)int型spinbox代理编辑器
同1)
三、使用自定义代理类
1、定义代理变量
引入tfloatspinboxdelegate.h,tspinboxdelegate.h,tcomboboxdelegate.h头文件后
TSpinboxDelegate *intSpinDelegate;
TFloatSpinboxDelegate *floatSpinDelegate;
TComboBoxDelegate *comboDelegate;
2、设置委托
ntspinBoxDelegate=new TSpinBoxDelegate(this);
//设置委托
ui->tableView->setItemDelegateForColumn(0,intspinBoxDelegate);//为测深设置委托
floatSpinDelegate=new TFloatSpinDelegate(this);
//设置委托
ui->tableView->setItemDelegateForColumn(1,floatSpinDelegate);//垂深
ui->tableView->setItemDelegateForColumn(2,floatSpinDelegate);//方位
ui->tableView->setItemDelegateForColumn(3,floatSpinDelegate);//总位移
comboBoxDelegate=new TComboBoxDelegate(this);
QStringList strList;
strList<<"优"<<"良"<<"可"<<"不合格";//选项列表
comboBoxDelegate->setItems(strList,false);//设置可编辑状态
ui->tableView->setItemDelegateForColumn(4,comboBoxDelegate);
QAbstractItemView类设置自定义代理函数,以下:
1)将delegate设置为整个视图的代理
void setItemDelegate(QAbstractItemDelegate *delegate);
2)为某一列设置自定义代理
void setItemDelegateForColumn(int column,QAbstractItemDelegate* *delegate);
3)为某一行设置自定义代理
void setItemDelegateForRow(int Row,QAbstractItemDelegate *delegate);