QAbstractItemDelegate,QStyledItemDelegate,QItemDelegate

    • QAbstractItemDelegate
    • QStyledItemDelegate
      • QStyledItemDelegate的子类化
    • QStyledItemDelegate vs QItemDelegate

QAbstractItemDelegate

QAbstractItemDelegate类被用于从model中展示和编辑数据。
在model/view架构中,QAbstractItemDelegate为委托提供接口和常用功能。委托在视图中展示独特的item项,处理模型数据的编辑。
QAbstractItemDelegate是model/view类之一,并且是Qt模型视图架构的一部分。
为了以自定义的方式渲染item,你必须实现paint()和sizeHint()函数。QItemDelegate类提供了这些函数的默认实现,如果不需要自定义渲染,不必子类化此类。

考虑下面例子,我们从QStyleItemDelegate类继承创建一个WidgetDelegate类,在paint()函数中进行绘制。

void WidgetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                             const QModelIndex &index) const
  {
      if (index.column() == 1) {
          int progress = index.data().toInt();

          QStyleOptionProgressBar progressBarOption;
          progressBarOption.rect = option.rect;
          progressBarOption.minimum = 0;
          progressBarOption.maximum = 100;
          progressBarOption.progress = progress;
          progressBarOption.text = QString::number(progress) + "%";
          progressBarOption.textVisible = true;

          QApplication::style()->drawControl(QStyle::CE_ProgressBar,
                                             &progressBarOption, painter);
      } else
          QStyledItemDelegate::paint(painter, option, index);

注意我们使用了QStyleOptionProgressBar并初始化了它的成员。然后使用当前的QStyle去绘制它。
为了提供自定义的编辑,有两种方法可以使用。

  • 第一种方法是创建一个editor widget并直接在item的上面显示。
    为了实现这种效果必须重新实现createEditor()函数来提供一个etidor widget,用setEditorData()函数将model中的数据填充至editor,用setModelData函数以便委托能够从editor中更新model数据。

  • 第二种方法是通过重新实现editorEvent()函数直接处理用户事件。


QStyledItemDelegate

QStyledItemDelegate类为模型中的数据项提供显示和编辑的工具。
在项视图中,当从models中显示数据时,e.g 一个QTableView,个别数据通过委托来绘制。同样,当一个item被编辑时,它提供一个editor widget,当编辑发生时置于item view的顶部。QStyledItemDelegate是所有Qt项视图的默认委托,创建后就被安装。

同样,QStyledItemDelegate也是Qt模型视图架构中的Model/View类之一。该委托允许展示和编辑数据,独立于模型和视图开发。
模型中items的项数据被分配了一个ItemDataRole,每一个item为每个role存储了一个QVariant变量。QStyledItemDelegate为用户预期的大多数通用数据类型实现了显示和编辑。包括bool,int,string等。
数据将会用不同方式的绘制,取决于模型中角色的不同。下表列出了委托能够处理角色和数据类型。通常能充分保证模型能为每个角色返回合适的数据,以决定视图中items的外观。
Editor能够用QItemEditorFactory创建。一个QItemEditorFactory提供的静态实例,安装在所有Item委托中。你可以使用setItemEditorFactory()设置一个自定义的工厂,或使用QItemEditorFactory::setDefaultFactory()设置一个默认的工厂。它是被编辑的以EditRole存储在Item model中的数据。QItemEditorFactory类中有关于Item editor工厂更高层级的介绍。Color Editor Factory例子显示了如何以工厂模式创建一个自定义的editor。可参考官方demo。

QStyledItemDelegate的子类化

 如果delegate不支持绘制你需要或想要定制items绘制的数据类型,该情况下你需要子类化QStyledItemDelegate,重新实现paint()函数和可能也会实现sizeHint函数。Paint()为每个项单独调用,和sizeHint函数一起,你能为他们每个item指定hint。

当重新实现paint函数时,一个典型的数据类型处理是可能是使用超类实现其他类型。

绘制check box指示器由当前style执行。Style也为不同数据角色的绘制数据指定了尺寸和边界矩形。项自身的边界矩形也由style计算。对于绘制已经支持的数据类型,向style询问边界矩形是一个好方法。QStyle对此进行了更详细的描述。

如果你想要改变任何一个由样式或复选框指标器绘制计算的边界矩形,可以子类化QStyle。注意,这些items的大小也受重写的sizeHint函数的影响。

一个自定义委托可以在不使用编辑器项目工厂的情况下提供编辑器是可能的。在这种情况下,以下虚函数必须重新实现。

  • createEditor()返回用于从模型中更改数据的小部件,并可重新实现自定义编辑行为。
  • setEditorData()为小部件提供要操作的数据。
  • updateEditorGeometry()确保编辑器在item视图上正确显示。
  • setModelData()将更新后的数据返回给模型。

QStyledItemDelegate vs. QItemDelegate

 从Qt 4.4开始,出现了两个委托类:QItemDelegate和QStyledItemDelegate。QStyledItemDelegate默认的委托。这两个类是独立类,可以为视图中的items提供编辑器。它们之间的区别在于,QStyledItemDelegate使用当前的样式来绘制其条目。因此,我们建议在实现定制委托或使用Qt样式表时使用QStyledItemDelegate作为基类。这两个类的代码大概是相等的,除非自定义委托需要使用样式来绘图。

如果你希望定制项目items的绘制,应该实现一个自定义样式。可参阅QStyle类文档

你可能感兴趣的:(Qt,Document,delegate)