視圖代理

                    代理就是一箇中間人的意思,也就是model和view之間的一箇中間件,它協調二者之間的數據處理,以保證數據在顯示層和model層的一致性。app

                    在qt中實現本身的一個代理,通常繼承自QItemDelegate類,固然也能夠是QAbstractItemDelegate。框架

                    在作代理的時候,咱們首先要明確一些問題,咱們的編輯控件是什麼,設置它的值,修改怎麼影響model,編輯控件的樣式什麼樣,大小位置是否考慮。在qt中這些須要實現本身代理的方面都以虛函數的形式給出,在實現本身代理的時候,從新實現這些虛函數就行,而調用是自動的,這就是利用C++多態,實現了開閉。函數

                    下面給出一個例子ui

                    

#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知道這些虛函數是怎麼調用的,加深對整個框架運行機制的理解                  
相關文章
相關標籤/搜索