9.Delegate類

Concepts
     不像MVC模式,Model/View模式並無單獨用來處理事件和用戶交互的組件(controller)。一般,視圖負責向用戶呈現模型中的數據,並處理用戶的輸入。有時,爲了讓輸入更加靈活,使用Delegate處理交互。Delegate組件提供輸入功能,還負責渲染某個Item。Delegate的標準接口在QAbstractItemDelegate中定義。
     Delegate但願實現paint()和sizeHint()函數來呈現本身的內容。可是,簡單的基於Widget的Delegate經過QItemDelegate子類化,而不是QAbstractItemDelegate,而且有這些函數的默認實現。
     Delegate的Editors能夠用過Widget管理Edit過程或者直接處理事件,這兩種方式實現。第一種方法將在 spin box delegate 例子中實現。
     Pixelato例子顯示如何專門爲TableView建立定製的Delegate。
 
Using an existing delegate
     Qt提供的標準視圖都是經過QItemDelegate實例來實現編輯功能。默認的Delegate接口實現,以一般的樣式渲染每一個標準視圖:QListView,QTreeView,QTableView。
     全部的standard roles都由標準視圖使用的默認Delegate來處理。視圖使用的Delegate由itemDelegate()函數返回。setItemDelegate()函數容許您爲標準視圖安裝自定義Delegate。 
 
Delegate舉例: 咱們顯示一個4x2的表格,表格中每一個單元都是spinbox。
 
思考:
1.咱們使用QTableView顯示這個表格。
2.使用QStandardItemModel,初始化時指定4行2列。
3.渲染每一個表格爲spinbox,這裏就須要QItemDelegate。
4.QItemDeleate實現了paint()和sizeHint()函數。咱們不須要從新這2個函數。
5.每一個表格變成spinbox,須要實現createEditor()函數。
6.表格中數據改變,須要告訴Model,實現setModelData()函數
7.表格中數據改變,顯示也要跟着改變,實現setEditorData()函數。
8.最後數據改變,單元格的空間也可能改變,實現updataEditorGeometry()函數。
 
代碼以下:
spinboxdelegate.h
#ifndef SPINBOXDELEGATE_H
#define SPINBOXDELEGATE_H

#include <QItemDelegate>

class SpinBoxDelegate : public QItemDelegate
{
    Q_OBJECT
public:
    explicit 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;
signals:
    
public slots:
    
};

#endif // SPINBOXDELEGATE_H

 

sinboxdelegate.cpp函數

#include "spinboxdelegate.h"

#include <QSpinBox>

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

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

    return editor;
}
void SpinBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    QSpinBox *spinBox = static_cast<QSpinBox *>(editor);

    spinBox->interpretText();
    int num = index.data(Qt::DisplayRole).toInt();
    spinBox->setValue(num);
}

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

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

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

main.cppspa

#include <QTableView>
#include <QStandardItemModel>
#include <QModelIndex>
#include <QApplication>

#include <spinboxdelegate.h>

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

    QStandardItemModel *standardModel = new QStandardItemModel(4,2);
    QTableView *tableView = new QTableView;

    tableView->setModel(standardModel);
    for(int row = 0; row < 4; row++) {
        for(int col = 0; col < 2; col++) {
            QModelIndex index = standardModel->index(row, col, QModelIndex());
            standardModel->setData(index, QVariant((row+1)*(col+1)));
        }
    }

    SpinBoxDelegate *delegate = new SpinBoxDelegate;
    tableView->setItemDelegate(delegate);

    tableView->show();



    return a.exec();
}

 

程序效果以下:3d

      

相關文章
相關標籤/搜索