zoukankan      html  css  js  c++  java
  • 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

    未完待续...

    温故知新&&总结记录
  • 相关阅读:
    【前端知识体系-JS相关】组件化和React
    【前端知识体系-JS相关】虚拟DOM和Diff算法
    【前端知识体系-JS相关】ES6专题系列总结
    【前端开发环境】前端使用GIT管理代码仓库需要掌握的几个必备技巧和知识点总结
    webpack代码分离CommonsChunkPlugin插件的使用(防止重复)
    webpack管理输出
    webpack管理资源(loader操作)
    window启动webpack打包的三种方法
    echarts地图map城市间如何连线
    echarts水球图编写
  • 原文地址:https://www.cnblogs.com/yuemw/p/7899382.html
Copyright © 2011-2022 走看看