概念:
不同于模型 - 视图 - 控制器模式,模型/视图设计不包括用于管理与用户交互的一个完全独立的组件。一般情况,视图负责将模型数据呈现给用户以及处理用户输入。为了输入更加具有灵活性,则由委托来执行交互。这些组件提供输入功能,且在一些视图中还负责渲染个别项目。控制委托的标准接口在QAbstractItemDelegate类中定义。
简单基础部件的委托可以继承QItemDelegate,并使用这些函数的默认实现,委托编辑器可以通过使用小工具来管理编辑过程或直接处理事件来实现。
使用Delegate的原因:Qt中当用到QTreeView和QTableView等用于显示item的视图时,你要编辑一个item用到的编辑工具可能是除了默认文字编辑lineEdit以外的工具,例如button,spinBox,甚至Slider,ProgressBar,也有可能是自定义的widget。所以Qt提供了一个委托类,用来处理View中的数据展示方式
自定义委托示例:
当视图需要编辑器时,它会告知委托为被修改的项目提供一个编辑器部件,委托会调用 createEditor 函数提供一个合适的部件。
- 在自定义委托时,createEditor返回一个可编辑输入的控件对象,如果不需要编辑,则返回 nullptr, 返回的指针对象不需要保存,因为视图在不需要的时候会销毁它。
- setEditorData 函数将模型中的数据渲染到编辑器中。
- setModelData 函数在用户完成了输入之后,将数据存储到模型中。
updateEditorGeometry 函数用来调整编辑器的位置和大小,QStyleOptionViewItem对象提供了几何布局相关的信息。代理对象会在完成编辑后发射 closeEditor 信号来告知视图。
要使用委托需要重载下面这四个函数:
.h文件
//创建委托控件
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
//设置控件数据
void setEditorData(QWidget *editor,const QModelIndex &index) const override;
//设置模型数据
void setModelData(QWidget *editor,QAbstractItemModel *model,const QModelIndex &index) const override;
//设置控件位置
void updateEditorGeometry(QWidget *editor,const QStyleOption &option,const QModelIndex &index);
cpp文件
//创建委托控件
QWidget *ComBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
Q_UNUSED(index); //提示编译器,参数未使用
Q_UNUSED(option);
QComboBox *box = new QComboBox(parent);
//设置下拉列表的选项内容
QStringList strList;
strList<<tr("工人")<<tr("医生")<<tr("律师")<<tr("军人")<<tr("程序员");
box->addItems(strList);
return box;
}
//设置控件数据
void ComBoxDelegate::setEditorData(QWidget *editor,const QModelIndex &index) const
{
//获取单元格内容
QString str = index.data().toString();
QComboBox *box = static_cast<QComboBox*>(editor);
int currentIndex = box->findText(str);
if(currentIndex >= 0)
{
box->setCurrentIndex(currentIndex);
}
}
//设置模型数据
void ComBoxDelegate::setModelData(QWidget *editor,QAbstractItemModel *model,const QModelIndex &index) const
{
//获取编辑控件的内容
QString str = static_cast<QComboBox*>(editor)->currentText();
//设置模型数据
model->setData(index,str);
}
//设置控件位置
void ComBoxDelegate::updateEditorGeometry(QWidget *editor,const QStyleOption &option,const QModelIndex &index)
{
Q_UNUSED(index);
//更新控件位置大小
editor->setGeometry(option.rect);
}
这里实现的委托使用QComBox来提供编辑功能,主要用于模型处理一些下拉列表的选择功能,因为自定义委托控制数据输入。我们构造了一个表视图来显示模型的内容,可以使用自定义的委托来进行编辑