Qt 模式视图框架解读之委托

3、委托类

Qt中的模型、视图结构中没有包含一个完全分离的组件来处理与用户的交互。

一般地、视图用来将模型中的数据展示给用户,也用来处理用户的输入。为了获得更高的灵活性,交互可以交给委托来执行。

控制委托的标准接口在QAbstractItemDelegate类中定义。

委托通过实现paint()和sizeHint()来使它们可以渲染自身的内容。

基于部件的委托可以通过子类化QItemDelegate来实现。

委托的编辑器可以通过两种方式来实现,

一、使用部件来管理编辑过程。

二、直接处理事件。

可以参考Qt提供的Spin Box Delegate的示例程序,如下:

在这里插入图片描述

委托:顾明思议,使用标准Qt 的编辑器编辑(standard QT editor widget),然后再将数据返回到视图中。

先看下SpinBoxDelegate Class Definition:


  class SpinBoxDelegate : public QStyledItemDelegate
  {
      Q_OBJECT

  public:
      SpinBoxDelegate(QObject *parent = nullptr);

      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;
  };

上述类的定义中做了如下几项事情:
1、创建 一个编辑部件,并在视图中的确定位置显示。
2、与数据模型通信。

另外,自定义模型可以通过paintEvent来提供自定义的painting code
当然,还可以通过重载destroyEditor()函数来实现可编辑部件的重复使用。

SpinBoxDelegate 类成员的实现:
委托常常代码量是非常少的。构造韩式也仅仅需要调用类默认的构造函数即可。
1、构造函数:

 SpinBoxDelegate::SpinBoxDelegate(QObject *parent)
      : QStyledItemDelegate(parent)
  {
  }

2、createEditor():该函数返回一个可编辑部件,并且将从数据模型中获得的数据的值限定在0到100之间。

  QWidget *SpinBoxDelegate::createEditor(QWidget *parent,
                                         const QStyleOptionViewItem &/* option */,
                                         const QModelIndex &/* index */) const
  {
      QSpinBox *editor = new QSpinBox(parent);
      editor->setFrame(false);
      editor->setMinimum(0);
      editor->setMaximum(100);

      return editor;
  }

3、setEditorData(): 从模型中读到数据,并将它转化为整形,然后写到这个可编辑的部件中。

  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);
  }

4、setModelData(): 从spin box 中读到数据,并将数据写入到数据模型中。


  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);
  }

这里的interpretText()函数,是为了让我们获得到的是spin box 中最新的的数据。

5、updateEditorGeometry():更新可编辑部件的几何形状,这是委托机制中必不可少的。


  void SpinBoxDelegate::updateEditorGeometry(QWidget *editor,
                                             const QStyleOptionViewItem &option,
                                             const QModelIndex &/* index */) const
  {
      editor->setGeometry(option.rect);
  }

主函数的实现

主函数实现以下几方面内容:
1、通过标准数据模型来创建数据项;
2、建立表格视图来显示这些数据项;
3、创建一个委托来编辑数据;


  int main(int argc, char *argv[])
  {
      QApplication app(argc, argv);

      QStandardItemModel model(4, 2);
      QTableView tableView;
      tableView.setModel(&model);

      SpinBoxDelegate delegate;
      tableView.setItemDelegate(&delegate);

      for (int row = 0; row < 4; ++row) {
          for (int column = 0; column < 2; ++column) {
              QModelIndex index = model.index(row, column, QModelIndex());
              model.setData(index, QVariant((row + 1) * (column + 1)));
          }
      }

      tableView.setWindowTitle(QObject::tr("Spin Box Delegate"));
      tableView.show();
      return app.exec();
  }

由于委托继承自QStyledItemDelegate,每一个单元格会通过标准绘图操作绘制。(这句话的理解就是,当单元格被操作的时候,会建立委托,而这个委托的视图是通过标准的绘图操作来实现)

到这里,这个spin box delegate的介绍就结束了。想必多操作,多练习自然就明白了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值