Qt mvc四

53 篇文章 2 订阅
53 篇文章 36 订阅

上次提到对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类中的使用像这样

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实体类也要支持对修改的支持

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的setData

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;

}

运行的结果图

我修改了我的名字



图不贴了,有兴趣的可以留个邮箱我发代码


补上save的代码

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();

    }

}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Qt中的MVCModel-View-Controller)模式是一种常用的软件架构模式,用于将应用程序的数据、用户界面和业务逻辑分离开来,以实现更好的代码组织和可维护性。 在Qt中,MVC模式可以通过自定义的控制器来实现。具体来说,QtMVC架构可以描述为Model/View,并通过自定义的控制器来实现Model/View/Controller的设计模式。 在这种架构中,Model负责管理应用程序的数据,View负责显示数据和与用户交互,而Controller负责处理用户输入并更新Model和View之间的关系。 通过使用MVC模式,可以实现以下优点: 1. 分离关注点:MVC模式将数据、用户界面和业务逻辑分离开来,使得代码更易于理解和维护。 2. 可扩展性:由于模块之间的松耦合性,可以更容易地添加新的功能或修改现有功能。 3. 可重用性:通过将数据和界面分离,可以更容易地重用模型和视图组件。 4. 可测试性:由于模块之间的明确分离,可以更容易地对模型、视图和控制器进行单元测试。 以下是一个简单的示例代码,演示了如何在Qt中实现MVC架构: ```cpp // Model class DataModel : public QObject { Q_OBJECT public: // 数据相关的方法和属性 }; // View class DataView : public QWidget { Q_OBJECT public: // 显示数据和处理用户交互的方法和属性 }; // Controller class DataController : public QObject { Q_OBJECT public: DataController(DataModel* model, DataView* view) : m_model(model), m_view(view) { // 处理用户输入并更新模型和视图之间的关系 } private: DataModel* m_model; DataView* m_view; }; int main(int argc, char *argv[]) { QApplication app(argc, argv); // 创建模型、视图和控制器 DataModel model; DataView view; DataController controller(&model, &view); // 显示视图 view.show(); return app.exec(); } ``` 这个示例代码展示了一个简单的MVC架构,其中Model负责管理数据,View负责显示数据和与用户交互,Controller负责处理用户输入并更新Model和View之间的关系。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值