Delegate 类编辑器
概念函数
与MVC模式不一样,model/view结构没有用于与用户交互的彻底独立的组件。通常来说, view负责把数据展现布局
给用户,也处理用户的输入。为了得到更多的灵性性,交互经过delegagte执行。它既提供输入功能又负责渲染view中的每一个数据项。 控制delegates的标准接口在QAbstractItemDelegate类中定义。Delegates经过实现paint()和sizeHint()以达到渲染内容的目的。然而,简单的基于widget的delegates,能够从QItemDelegate子类化,而不是QAbstractItemDelegate,这样可使用它提供的上述函数的缺省实现。delegate可使用widget来处理编辑过程,也能够直接对事件进行处理。学习
使用现成的delegatespa
Qt提供的标准views都使用QItemDelegate的实例来提供编辑功能。它以普通的风格来为每一个标准view渲染数据项。这些标准的views包括:QListView,QTableView,QTreeView。全部标准的角色都经过标准views包含的缺省delegate进行处理。一个view使用的delegate能够用itemDelegate()函数取得,而setItemDelegate() 函数能够安装一个定制delegate。指针
一个简单的delegatehtm
这个delegate使用QSpinBox来提供编辑功能。它主要想用于显示整数的models上。尽管咱们已经创建了一个基于整数的table model,但咱们也可使用QStandardItemModel,由于delegate能够控制数据的录入。咱们又建了一个table view来显示model的内容,用咱们定制的delegate来编辑。blog
咱们从QItemDelegate子类化,这样能够利用它缺省实现的显示功能。固然咱们必需提供函数来管理用于编辑的widget:接口
class SpinBoxDelegate : public QItemDelegate
{
Q_OBJECT
public:
SpinBoxDelegate(QObject *parent = 0);
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;
};
须要注意的是,当一个delegate建立时,不须要安装一个widget,只有在真正须要时才建立这个用于编辑的widget。
提供编辑器
在这个例子中,当table view须要提供一个编辑器时,它要求delegate提供一个可用于编辑的widget,它应该适用于当前正被修改的数据项。这正是createEditor()函数应该实现的:
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;
}
咱们不须要跟踪这个widget的指针,由于view会在不须要时销毁这个widget。咱们也给编辑安装了delegate缺省的事件过滤器,这提供了用户指望的标准编辑快捷键。view经过咱们定义相应的函数来保证编辑器的数据与几何布局被正确的设置。咱们也能够根据不一样的model index来建立不一样的编辑器,好比,咱们有一列整数,一列字符串,咱们能够根据哪一种列被编辑来建立一个QSpinBox或是QLineEdit。delegate必需提供一个函数把model中的数据拷贝到编辑器中。
void SpinBoxDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
int value = index.model()->data(index, Qt::DisplayRole).toInt();
QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
spinBox->setValue(value);
}
向model提交数据
这须要咱们实现另一个函数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);
}
标准的QItemDelegate类当它完成编辑时会发射closeEditor()信号来通知view。view保证编辑器widget关闭与销毁。本例中咱们只提供简单的编辑功能,所以不须要发送个信号。
更新编辑器几何布局
delegate负责管理编辑器的几何布局。这些几何布局信息在编辑建立时或view的尺寸位置发生改变时,
都应当被提供。幸运的是,view经过一个view option能够提供这些必要的信息。
void SpinBoxDelegate::updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
{
editor->setGeometry(option.rect);
}
编辑提示
编辑完成后,delegate会给别的组件提供有关于编辑处理结果的提示,也提供用于后续编辑操做的一些提示。
这能够经过发射带有某种hint的closeEditor()信号完成。这些信号会被安装在spin box上的缺省的QItemDelegate事件过滤器捕获。对这个缺省的事件过滤来说,当用户按下回车键,delegate会对model中的数据进行提交,并关闭spin box。
咱们能够安装本身的事件过滤器以迎合咱们的须要,例如,咱们能够发射带有EditNextItem hint的
closeEditor()信号来实现自动开始编辑view中的下一项。