MVC架构之delegate

Qt的MVC架构可以实现很多数据显示的功能,本次主要对代理进行一个总结:

重实现QStyledItemDelegate类,实现自定义类。

(1)ComboxDelegate.h

#ifndef COMBODELEGATE_H
#define COMBODELEGATE_H

#include <QStyledItemDelegate>

class ComboDelegate : public QStyledItemDelegate
{
public:
    ComboDelegate(QObject *parent = NULL);

protected:
    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 // COMBODELEGATE_H

(2)ComboDelegate.cpp

#include "ComboDelegate.h"
#include <QComboBox>

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

QWidget *ComboDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    Q_UNUSED(option);
    Q_UNUSED(index);

    QStringList list;
    list << "工人" << "农民" << "军人" << "律师";

    QComboBox *pEditor = new QComboBox(parent);
    pEditor->addItems(list);
    pEditor->installEventFilter(const_cast<ComboDelegate*>(this));
    return pEditor;
}

void ComboDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    QString strText = index.model()->data(index).toString();
    QComboBox *pCombox = NULL;
    pCombox = static_cast<QComboBox*>(editor);
    if (pCombox != NULL)
    {
        int nIndex = pCombox->findText(strText);
        pCombox->setCurrentIndex(nIndex);
    }
}

void ComboDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index)const
{
    QComboBox *pCombox = NULL;
    pCombox = static_cast<QComboBox*>(editor);
    if (pCombox != NULL)
    {
        QString strText = pCombox->currentText();
        model->setData(index, strText);
    }
}

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

(3)DateDelegate.h

#ifndef DATEDELEGATE_H
#define DATEDELEGATE_H

#include <QStyledItemDelegate>

class DateDelegate : public QStyledItemDelegate
{
public:
    DateDelegate(QObject *parent = NULL);

protected:
    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 // DATEDELEGATE_H

(4)DateDelegate.cpp

#include "DateDelegate.h"
#include <QDateTimeEdit>

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

// 首先创建要进行代理的窗体
QWidget *DateDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    Q_UNUSED(option);
    Q_UNUSED(index);

    QDateTimeEdit *pEditor = new QDateTimeEdit(parent);      // 一个日历的控件
    pEditor->setDisplayFormat("yyyy-MM-dd");   // 日期时间的显示格式
    pEditor->setCalendarPopup(true);   // 以下拉的方式显示
    pEditor->installEventFilter(const_cast<DateDelegate*>(this));  // 调用这个函数安装事件过滤器,使这个对象可以捕获QDateTimeEdit对象的事件
    return pEditor;
}

// 这个是初始化作用,初始化代理控件的数据
void DateDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
  // 先用这个index返回这个model然后用这个model得到index对应的数据
  QString strDate = index.model()->data(index).toString();
  QDate date = QDate::fromString(strDate, Qt::ISODate);     // 根据QString类型得到相应的时间类型
  QDateTimeEdit *pEditor = NULL;
  pEditor = static_cast<QDateTimeEdit*>(editor);    // 强转为QDateTimeEdit*类型
  if (pEditor != NULL)
  {
      pEditor->setDate(date);      // 设置代理控件的显示数据
  }
}

// 将代理控件里面的数据更新到视图控件中
// void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
void DateDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
  QDateTimeEdit *pEditor = NULL;
  pEditor = static_cast<QDateTimeEdit*>(editor);    // 得到时间
  if (pEditor != NULL)
  {
      QDate date = pEditor->date();    // 得到时间
      model->setData(index, QVariant(date.toString(Qt::ISODate)));    // 把值放到相应的index里面
  }
}

// 代理中数据的改变放到model中
// void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void DateDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    Q_UNUSED(index);
    editor->setGeometry(option.rect);
}

(5)SpinDelegate.h

#ifndef SPINDELEGATE_H
#define SPINDELEGATE_H

#include <QStyledItemDelegate>

class SpinDelegate : public QStyledItemDelegate
{
public:
    SpinDelegate(QObject *parent = NULL);

protected:
    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 // SPINDELEGATE_H

(6)SpinDelegate.cpp

#include "SpinDelegate.h"

#include <QSpinBox>

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

QWidget *SpinDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    Q_UNUSED(option);
    Q_UNUSED(index);

    QSpinBox *pEditor = new QSpinBox(parent);
    pEditor->setRange(0, 30000);
    pEditor->installEventFilter(const_cast<SpinDelegate*>(this));
    return pEditor;
}

void SpinDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    int value = index.model()->data(index).toInt();
    QSpinBox *pSpinbox = NULL;
    pSpinbox = static_cast<QSpinBox*>(editor);
    if (pSpinbox != NULL)
    {
        pSpinbox->setValue(value);
    }
}

void SpinDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    QSpinBox *pSpinbox = NULL;
    pSpinbox = static_cast<QSpinBox*>(editor);
    if (pSpinbox != NULL)
    {
        int value = pSpinbox->value();
        model->setData(index, value);
    }
}

void SpinDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    Q_UNUSED(index);

    editor->setGeometry(option.rect);
}

(7)main.cpp

#include <QApplication>
#include <QFile>
#include <QDebug>
#include <QWidget>
#include <QTableView>
#include <QTextStream>
#include <QStandardItemModel>
#include "DateDelegate.h"
#include "ComboDelegate.h"
#include "SpinDelegate.h"

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

    QStandardItemModel model(4, 4);
    model.setHeaderData(0, Qt::Horizontal, QLatin1String("Name"));
    model.setHeaderData(1, Qt::Horizontal, QLatin1String("Birthday"));
    model.setHeaderData(2, Qt::Horizontal, QLatin1String("Job"));
    model.setHeaderData(3, Qt::Horizontal, QLatin1String("Income"));

    QFile file(QLatin1String("/mnt/liuy/info"));
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        qDebug() << "open the file failed...";
        return -1;
    }

    QTextStream out(&file);
    QString line;
    model.removeRows(0, model.rowCount(QModelIndex()), QModelIndex());
    int row = 0;
    do
    {
        line = out.readLine();
        if (!line.isEmpty())
        {
            model.insertRows(row, 1, QModelIndex());
            QStringList pieces = line.split(",", QString::SkipEmptyParts);
            model.setData(model.index(row, 0, QModelIndex()), pieces.value(0));
            model.setData(model.index(row, 1, QModelIndex()), pieces.value(1));
            model.setData(model.index(row, 2, QModelIndex()), pieces.value(2));
            model.setData(model.index(row, 3, QModelIndex()), pieces.value(3));
            ++row;
        }
    } while(!line.isEmpty());
    file.close();

    QTableView tableView;
    tableView.setModel(&model); // 绑定Model
    tableView.setWindowTitle(QLatin1String("Delegate"));

    DateDelegate dateDelegate;
    tableView.setItemDelegateForColumn(1, &dateDelegate); // 第一列代理
    ComboDelegate comboDelegate;
    tableView.setItemDelegateForColumn(2, &comboDelegate);// 第二列代理
    SpinDelegate spinDelegate;
    tableView.setItemDelegateForColumn(3, &spinDelegate); // 第三列代理

    tableView.resize(500, 300); // 重置大小
    tableView.show();

    return a.exec();
}

信息文件

文件info 内容如下(注意:文件格式):

Liu,1977-01-05,工人,1500
Wang,1987-11-25,医生,2500
Sun,1967-10-05,军人,500
Zhang,1978-01-12,律师,4500

运行效果图如下:

第二列编辑图(时间日期控件):

第三列编辑图(下拉框控件):

第四列编辑图(微调框控件):

 引用:http://www.cnblogs.com/Braveliu/p/7488250.html

未完待续...

温故知新&&总结记录
原文地址:https://www.cnblogs.com/yuemw/p/7899382.html