Qt mvc四

上次提到對student類屬性的描述是侵入式的,此次介紹非侵入式的,其實我也就是借鑑了便準庫中的traits,瞭解的同窗應該都知道,不瞭解的能夠查查。函數

我定義了一個類模板,Members,對於類student模板提供了一個特化學習

/************************************************
*
*author:周翔
*e-mail:604487178@qq.com
*blog:http://blog.csdn.net/zhx6044
*
*
*************************************************/

#ifndef MEMBERS_HPP
#define MEMBERS_HPP

#include <QString>

#include "student.hpp"

template <typename T>
class Members
{
public:
    static int members() {
        return 0;
    }
    static QString describe(int /*i*/) {
        return QString();
    }
};

template <>
class Members<Student>
{
public:
    static int members() {
        return 3;
    }
    static QString describe(int i) {
        switch (i) {
        case 0:
            return "No.";
        case 1:
            return "Name";
        case 2:
            return "Sex";
        default:
            break;
        }
        return QString();
    }
};

#endif // MEMBERS_HPP

那些model類中的使用像這樣spa

int DataTableModel::columnCount(const QModelIndex &/*parent*/) const
{
    return Members<T>::members();
}

QVariant DataTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (role != Qt::DisplayRole) {
        return QVariant();
    }
    if (orientation == Qt::Vertical) {
        return QString("row %1").arg(section);
    } else {
        return Members<T>::describe(section);
    }
    return QVariant();
}

前面咱們只是提供了簡單的加載顯示,這裏咱們容許修改model的數據,這個就用引出代理,在一的時候已經簡單介紹了,若是想詳細瞭解能夠直接看文檔(qt的文檔是我見過最好的,是學習的好資料)。咱們例子的數據項是三項,前面兩項都是編輯是能夠是文本編輯,最後一個不是男就是女,仍是選擇的好。因此咱們引入兩個代理類LineEditDelegate和SexComboBox,他們都繼承自QItemDelegate,你也能夠繼承自QAbstractItemDelegate,可是用的最多的是QStyledItemDelegate和QItemDelegate,看名字也知道他們之間的區別。下面是LineEditDelegate


/************************************************
*
*author:周翔
*e-mail:604487178@qq.com
*blog:http://blog.csdn.net/zhx6044
*
*
*************************************************/

#ifndef LINEEDITDELEGATE_HPP
#define LINEEDITDELEGATE_HPP

#include <QItemDelegate>
#include <QLineEdit>

class LineEditDelegate : public QItemDelegate
{
    Q_OBJECT
public:
    explicit LineEditDelegate(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 // LINEEDITDELEGATE_HPP

/************************************************
*
*author:周翔
*e-mail:604487178@qq.com
*blog:http://blog.csdn.net/zhx6044
*
*
*************************************************/

#include "lineeditdelegate.hpp"

LineEditDelegate::LineEditDelegate(QObject *parent) :
    QItemDelegate(parent)
{
}
QWidget* LineEditDelegate::createEditor(QWidget *parent,
                                        const QStyleOptionViewItem &/*option*/,
                                        const QModelIndex &/*index*/) const
{
    QLineEdit *w = new QLineEdit(parent);
    return w;
}

void LineEditDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    QLineEdit *w = static_cast<QLineEdit*>(editor);
    w->setText(trUtf8("%1").arg(index.model()->data(index,Qt::DisplayRole).toString()));
}
void LineEditDelegate::setModelData(QWidget *editor,
                                    QAbstractItemModel *model,
                                    const QModelIndex &index) const
{
    QString value = static_cast<QLineEdit*>(editor)->text();
    model->setData(index,value,Qt::EditRole);
}
void LineEditDelegate::updateEditorGeometry(QWidget *editor,
                                            const QStyleOptionViewItem &option,
                                            const QModelIndex &/*index*/) const
{
    editor->setGeometry(option.rect);

}

SexComboBox

/************************************************
*
*author:周翔
*e-mail:604487178@qq.com
*blog:http://blog.csdn.net/zhx6044
*
*
*************************************************/

#ifndef SEXCOMBOBOX_HPP
#define SEXCOMBOBOX_HPP

#include <QItemDelegate>
#include <QComboBox>

class SexComboBox : public QItemDelegate
{
    Q_OBJECT
public:
    explicit SexComboBox(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 // SEXCOMBOBOX_HPP

/************************************************
*
*author:周翔
*e-mail:604487178@qq.com
*blog:http://blog.csdn.net/zhx6044
*
*
*************************************************/

#include "sexcombobox.hpp"

SexComboBox::SexComboBox(QObject *parent) :
    QItemDelegate(parent)
{
}
QWidget* SexComboBox::createEditor(QWidget *parent, const QStyleOptionViewItem &/*option*/,
                                   const QModelIndex &/*index*/) const
{
    QComboBox *w = new QComboBox(parent);
    w->addItems(QStringList() << trUtf8("男") << trUtf8("女"));
    return w;
}

void SexComboBox::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    QComboBox *w = static_cast<QComboBox*>(editor);
    QString sex = index.model()->data(index,Qt::DisplayRole).toString();
    w->setCurrentIndex(w->findText(sex));
}

void SexComboBox::setModelData(QWidget *editor, QAbstractItemModel *model,
                               const QModelIndex &index) const
{
    QComboBox *w = static_cast<QComboBox*>(editor);
    QString sex = w->currentText();
    model->setData(index,sex,Qt::EditRole);
}

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

若是對這些須要實現的函數不怎麼清除能夠看我之前的視圖代理那篇。我想要提醒的注意點是setEditorData和setModelData在設置數據角色時注意,要和model中一致。

實現對model中數據的修改須要在model中實現setData,那咱們的student實體類也要支持對修改的支持.net

student代理

friend QTextStream& operator <<(QTextStream &out,const Student &t) {
        out << t.m_no  <<"   "<< t.m_name <<"   "<< t.m_sex << '\n';
        return out;
    }

  /**
     * @brief operator [] be called by the function 'data' in model
     * @param i
     * @return
     */
    const QString& operator [](int i) const{

        switch (i) {
        case 0:
            return m_no;
        case 1:
            return m_name;
            // case 2:

        default:
            return m_sex;
            //break;
        }
        //return QString();
    }
    /**
     * @brief operator [] be called by the function 'setData' in model
     * @param i
     * @return
     */
    QString& operator [](int i) {
        switch (i) {
        case 0:
            return m_no;
        case 1:
            return m_name;
            //        case 2:
            //            return m_sex;
        default:
            return m_sex;
            //break;
        }

    }

重載<<將修改過的數據寫回文件,[]看註釋,關於const和非const請同窗本身早資料瞭解

model的setDatacode

bool DataTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (role != Qt::EditRole) {
        return false;
    } else {
        m_data[index.row()][index.column()] = value.toString();
        return true;
    }
    return false;

}

運行的結果圖

我修改了個人名字blog



圖不貼了,有興趣的能夠留個郵箱我發代碼繼承


補上save的代碼ci

void DataTableModel::save()
{

    QFile file(m_fileName);
    if (!file.open(QIODevice::WriteOnly)) {
        emit sig_error("save data failure!");
    } else {
        QTextStream out(&file);
        for (std::vector<T>::const_iterator it = m_data.begin();it != m_data.end();++it) {
            out << (*it);
        }
        file.close();

    }

}
相關文章
相關標籤/搜索