模型-视图-代理(Model-View-Delegate)-实战篇

引言

经过上一章的理论学习,接下来我们写个例子来实践一番
我们就以实现SPinbox 的代理为例子

代码

SpinBoxDelegate 类的头文件

spinboxdelegate.h

#ifndef SPINBOXDELEGATE_H
#define SPINBOXDELEGATE_H
#include 
#include 
#include 

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;

};

#endif // SPINBOXDELEGATE_H

spinboxdelegate.cpp

#include "spinboxdelegate.h"
#include 
#include 

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

QWidget *SpinBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/* option */,
    const QModelIndex &/* index */) const
{
    QSpinBox *editor = new QSpinBox(parent);

    editor->setRange(0,10000);

    editor->installEventFilter(const_cast(this));

    return editor;

}

void SpinBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    int value = index.model()->data(index, Qt::EditRole).toInt();

    QSpinBox *spinBox = static_cast(editor);

    spinBox->setValue(value);

}

void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
                                   const QModelIndex &index) const
{
    QSpinBox *box = static_cast(editor);
    int value = box->value();
    model->setData(index,value);
}

void SpinBoxDelegate::updateEditorGeometry(QWidget *editor,
    const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
{
    editor->setGeometry(option.rect); // option.rect属性中保存了条目的位置,这里将控件设置在刚好占住条目的位置
}

必须要重写前三个函数:
- 1.QWidget*createEditor() 提供一个编辑器,告诉model用的是那个编辑器进行数据的编辑和选择
- 2.void setEditorData() 为editor提供编辑的原始数据, 从model中读取数据,设置编辑器显示的数据
- 3.void setModelData( ) 根据editor 的数据更新model的数据,从编辑器中读取当前显示的数据,设置model中的数据.
- 4.void updateEditorGeometry( ) 保证editor显示在 item view 的合适位置以及大小

MyWidget 构造函数

#include "MyWidget.h"
#include "ui_MyWidget.h"
#include"spinboxdelegate.h"
#include
#include
#include

MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyWidget)
{
    ui->setupUi(this);

    //定义一个模型 大小是4*4 的
    QStandardItemModel *tableModel=new QStandardItemModel(4,4,this);

    //定义一个SpinBox功能的代理
    SpinBoxDelegate *spinDelegate=new SpinBoxDelegate;

    //设置表头名称
    tableModel->setHeaderData(0,Qt::Horizontal,tr("帮派"));
    tableModel->setHeaderData(1,Qt::Horizontal,"姓名");
    tableModel->setHeaderData(2,Qt::Horizontal,"花名");
    tableModel->setHeaderData(3,Qt::Horizontal,"排行");

    //显示
    QTableView *tabletView=new QTableView;
    //显示的模式
    tabletView->setModel(tableModel);
    //代理作用于第三列
    tabletView->setItemDelegateForColumn(3,spinDelegate);

    //设置显示的布局和大小
    QHBoxLayout *mainLayout=new QHBoxLayout(this);
    mainLayout->addWidget(tabletView);
    this->resize(600,400);
}

MyWidget::~MyWidget()
{
    delete ui;
}

效果

模型-视图-代理(Model-View-Delegate)-实战篇_第1张图片

小结

在上面重写的四个方法中
首先执行的是
- 1.QWidget*createEditor() 设置代理成功了,创建编辑区
- 2.void updateEditorGeometry( ) 随后设置显示Item的位置
- 3.void setEditorData() 接着给编辑区设置数据 是给Spinbox 赋值
- 4.void setModelData( ) 数据在同步到Model上 是给Model设置值

猜测
在UI 上的显示在第三部就已经 显示了
但是为了MV 的数据同步,所以在给Model设置数据,来保证步骤3,4 的数据的同步与一致性。

若问题,请指正!!!

你可能感兴趣的:(模型-视图-代理(Model-View-Delegate)-实战篇)