一、 委托类
模型/视图结构中,一般的,视图用来将模型中的数据展示给用户,也用来处理用户的输入。为了获得更高的灵活性,交互可以由委托来执行。这些组件提供了输入功能,而且也负责渲染一些视图中的个别项目。控制委托的标准接口在QAbstractItemDelegate类中定义。
委托通过实现paint()和sizeHint()函数来使它们可以渲染自身的内容。简单的基于部件的委托可以通过子类化QItemDelegate来实现,这样可以使用这些函数的默认实现。可以使用itemDelegate()函数获取一个视图中使用的委托,使用setItemDelegate()函数为视图安装一个自定义委托。
二、自定义委托类
下面例子来说明如何使用现成的部件自定义委托。例子中使用QSpinBox来提供编辑功能,主要用于显示数据的模型。
在上一篇我的QT Creator学习笔记(三十一)——模型/视图编程之视图类工程的基础上,向项目中添加新的C++类,类名为SpinBoxDelegate,基类设置为QItemDelegate,将spinboxdelegate.h修改如下
#ifndef SPINBOXDELEGATE_H
#define SPINBOXDELEGATE_H
#include <QItemDelegate>
class SpinBoxDelegate : public QItemDelegate
{
Q_OBJECT
public:
explicit SpinBoxDelegate(QObject *parent = 0);
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 QStyleOptionViewItem &option, const QModelIndex &index) const override;
};
#endif // SPINBOXDELEGATE_H
这里面要重写父类的几个函数来管理编辑器部件。
在spinboxdelegate.cpp中依次添加几个函数的实现
构造函数
SpinBoxDelegate::SpinBoxDelegate(QObject *parent):QItemDelegate(parent)
{
}
创建编辑器函数
//创建编辑器
QWidget *SpinBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QSpinBox* editor=new QSpinBox(parent);
editor->setMinimum(0);
editor->setMaximum(100);
return editor;
}
为编辑器设置数据函数,在该函数中要在访问编辑器的成员函数之前,将它转化为合适的类型。
//为编辑器设置数据
void SpinBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
int value=index.model()->data(index,Qt::EditRole).toInt();
QSpinBox* spinBox=static_cast<QSpinBox*>(editor);
spinBox->setValue(value);
}
将数据写入模型。当用户完成了对QSpinBox部件中数据的编辑时,视图会通过调用setModelData()函数来告知委托将编辑好的数据存储到模型中。
//将数据写入到模型
void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QSpinBox* spinBox=static_cast<QSpinBox*>(editor);
spinBox->interpretText();
int value=spinBox->value();
model->setData(index,value,Qt::EditRole);
}
更新编辑器几何布局。委托有责任来管理编辑器的几何布局,必须在创建编辑器以及视图中项目大小或位置改变时,来设置它的几何布局,视图使用了一个QStyleOptionViewItem对象来提供来所有需要的几何布局信息。
//更新编辑器几何布局
void SpinBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
editor->setGeometry(option.rect);
}
最后,在mainwindow中使用自定义的委托类,在 mainwindow.cpp中包含spinboxdelegate.h文件,在构造函数中为tableView设置自定义委托
SpinBoxDelegate* delegate=new SpinBoxDelegate(this);
tableView->setItemDelegate(delegate);
运行效果如下