视图代理

53 篇文章 2 订阅
53 篇文章 36 订阅

                    代理就是一个中间人的意思,也就是model和view之间的一个中间件,它协调两者之间的数据处理,以保证数据在显示层和model层的一致性。

                    在qt中实现自己的一个代理,一般继承自QItemDelegate类,当然也可以是QAbstractItemDelegate。

                    在做代理的时候,我们首先要明确一些问题,我们的编辑控件是什么,设置它的值,修改怎么影响model,编辑控件的样式什么样,大小位置是否考虑。在qt中这些需要实现自己代理的方面都以虚函数的形式给出,在实现自己代理的时候,重新实现这些虚函数就行,而调用是自动的,这就是利用C++多态,实现了开闭。

                    下面给出一个例子

                    

#ifndef SPINBOXDELEGATE_H
#define SPINBOXDELEGATE_H
#include <QItemDelegate>
#include <QModelIndex>
#include <QObject>
#include <QSize>
#include <QSpinBox>

#define logger()  qDebug() << __FILE__ << __LINE__ << __func__

class SpinBoxDelegate : public QItemDelegate
{
    Q_OBJECT

public:
    SpinBoxDelegate(QObject *parent = 0);
    /**
      * @brief createEditor 进入可编辑的状态时,产生的编辑控件
      * @param parent 这个控件的上层控件
      * @param option 一些控件样式选择
      * @param index 所在的索引位置
      * @return 编辑控件的指针
      */
    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const;
    /**
      * @brief setEditorData 进入和推出编辑模式调用,修改view的值
      * @param editor 与改变想对应的editor指针
      * @param index model中的那个索引改变了值
      */
    void setEditorData(QWidget *editor, const QModelIndex &index) const;
    /**
      * @brief setModelData 退出编辑模式,修改model
      * @param editor 那个editor改变了
      * @param model 想对应的model
      * @param index 对应的索引
      */
    void setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const;
    /**
      * @brief updateEditorGeometry 更新位置
      * @param editor
      * @param option
      * @param index
      */
    void updateEditorGeometry(QWidget *editor,
                              const QStyleOptionViewItem &option, const QModelIndex &index) const;
};
/**
   这些虚函数是自动调用的,我们重新实现这些虚函数来达到控制的效果,可以重新实现的虚函数还有好几个,但是意义都是一样的

   */


#endif // SPINBOXDELEGATE_H
#include "spinBoxDelegate.h"

#include <QtGui>
#include <QDebug>


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

QWidget *SpinBoxDelegate::createEditor(QWidget *parent,
                                       const QStyleOptionViewItem &/* option */,
                                       const QModelIndex &/* index */) const
{
    logger();

    QSpinBox *editor = new QSpinBox(parent);//产生一个QSpinBox控件
    editor->setMinimum(0);
    editor->setMaximum(100);

    return editor;
}

void SpinBoxDelegate::setEditorData(QWidget *editor,
                                    const QModelIndex &index) const
{
    logger();
    int value = index.model()->data(index, Qt::EditRole).toInt();//根据index获得model的值

    QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
    spinBox->setValue(value);
}

void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
                                   const QModelIndex &index) const
{
    logger();
    QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
    spinBox->interpretText();
    int value = spinBox->value();

    model->setData(index, value, Qt::EditRole);
}

void SpinBoxDelegate::updateEditorGeometry(QWidget *editor,
                                           const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
{
    logger();
    editor->setGeometry(option.rect);
}
#include <QApplication>
#include <QHeaderView>
#include <QItemSelectionModel>
#include <QStandardItemModel>
#include <QTableView>

#include "spinBoxDelegate.h"

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

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

    SpinBoxDelegate delegate;
    tableView.setItemDelegate(&delegate);

    tableView.horizontalHeader()->setStretchLastSection(true);
    tableView.verticalHeader()->setStretchLastSection(true);

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

          可以根据打印的logger知道这些虚函数是怎么调用的,加深对整个框架运行机制的理解                  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值