Qt - 模型/视图编程(MVC编程-只读模型)

模型/视图编程

Qt中的模型/视图架构用来实现大量的数据存储、处理及显示。MVC(Model-View-Controller)包括了3个组件:模型(Model)是应用对象,用来表示数据;视图(View)是模型的用户界面,用来显示数据;控制(Controller)定义了用户界面对用户输入的反应方式。委托(Delegate)用于定制数据的渲染和编辑方式。

在这里插入图片描述

1.模型

所有的模型都基于QAbstractItemModel类,该类提供了十分灵活的接口来处理各种视图,这些视图可以将数据的表现形式为表格(table)、列表(list)、(tree)。
Qt提供了一些现成的模型来处理数据项:
QStringListModel 存储简单的QString项目列表;
QStandardItemModel管理复杂的属性结构数据项,每一个数据项可以包含任意的数据;
QFileSystemModel提供了本地文件系统中文件和目录信息;
QSqlQueryModelQSqlTableModelQSqlRelationTableModel用来访问数据库。
标准模型还无法满足需要时,可子类化QAbstractItemModelQAbstractListModelQAbstractTableModel来创建自定义的模型。
常见的3种模型为列表模型表格模型树模型,如下图所示:
在这里插入图片描述
为确保数据的表示与数据的获取相分离,Qt引入了模型索引的概念,输入和委托均可通过模型索引来请求数据并显示。只有模型需要知道怎样获取数据,被模型管理的数据类型可以被广泛的定义。模型索引包含一个指针,指向创建他们的模型,使用多个模型时可避免混淆。模型索引QModelIndex类提供对一块数据的临时引用,用来修改或检索模型中的数据,获取一个数据项的模型索引必须指定模型的3个属性:行号、列号和父项的模型索引。
QModelIndex index = model->index(row,column,parent);
也可通过模型指定的相关数据项对应的模型索引以及特定的角色来获取需要的类型数据,
QVariant value = model->data(index,role);
常用的角色类型:
在这里插入图片描述

2.视图

Qt提供了QListView、QTableView视图、QTreeView视图分别实现列表、表格与树视图效果。QListView将数据项显示为一个列表;QTableView将模型中的数据显示在一个表格中;QTreeView将模型中的数据项显示在具有层次的列表中。QTableView和QTreeView在显示项目的时候同时还可以显示标头,通过QHeaderView类实现。自定义视图类是基于QAbstractItemView抽象基类,如实现条形图,饼状图等特殊显示方式。

视图类的选择行为
在这里插入图片描述
视图类的选择模式
在这里插入图片描述
选择模型更新方式
在这里插入图片描述

具体操作

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
StringListModel : public QAbstrctListModel
在这里插入图片描述

在这里插入图片描述

具体代码

testModel.pro

在这里插入图片描述

stringlistmodel.h

在这里插入图片描述

#ifndef STRINGLISTMODEL_H
#define STRINGLISTMODEL_H

#include <QAbstractListModel>

class StringListModel : public QAbstractListModel
{
    Q_OBJECT
public:
    StringListModel(const QStringList &strings, QObject *parent = 0):QAbstractListModel(parent), m_stringList(strings){}

    //模型行数
    int rowCount(const QModelIndex &parent = QModelIndex()) const;

    //指定模型索引的数据项
    QVariant data(const QModelIndex &index, int role) const;

    //表头内容(数或表格)
    QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;

    //项目属性
    Qt::ItemFlags flags(const QModelIndex &index) const;

    //编辑数据
    bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);

    //插入行 参数(插入的位置, 插入等待行数, 父项的模型索引)
    bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex());

    //删除行
    bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex());

private:
    QStringList m_stringList;
};

#endif // STRINGLISTMODEL_H

stringlistmodel.cpp

在这里插入图片描述

#include "stringlistmodel.h"



int StringListModel::rowCount(const QModelIndex &parent) const
{
    return m_stringList.count();
}

QVariant StringListModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid()) return QVariant();

    if (index.row() == m_stringList.size()) return QVariant();

    if (role == Qt::DisplayRole || role == Qt::EditRole)
        return m_stringList.at(index.row());
    else
        return QVariant();
}

QVariant StringListModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (role != Qt::DisplayRole)
        return QVariant();

    //水平表头
    if (orientation == Qt::Horizontal)
        return QString("Column %1").arg(section);
    else
        return QString("Row %1").arg(section);
}

Qt::ItemFlags StringListModel::flags(const QModelIndex &index) const
{
    if (!index.isValid())
        return Qt::ItemIsEnabled;
    return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
}

bool StringListModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    //检测索引有效且项目可编辑
    if (index.isValid() && role == Qt::EditRole)
    {
        m_stringList.replace(index.row(), value.toString());
        emit dataChanged(index, index);
        return true;
    }

    return true;
}

bool StringListModel::insertRows(int position, int rows, const QModelIndex &index)
{
    //告知其他组件指定的行开始插入操作
    beginInsertRows(QModelIndex(), position, position + rows - 1);
    for (int row = 0; row < rows; ++row)
        m_stringList.insert(position, QString("来自星星的你"));
    //告别其他组件完成操作
    endInsertRows();
    return true;
}

bool StringListModel::removeRows(int position, int rows, const QModelIndex &index)
{
    //告别其他组件指定的行开始删除操作
    beginRemoveRows(QModelIndex(), position, position + rows - 1);
    for (int row = 0; row < rows; ++row)
    {
        m_stringList.removeAt(position);
    }

    //告别其他组件完成操作
    endRemoveRows();
    return true;
}


main.cpp

在这里插入图片描述

#include <QApplication>
#include "stringlistmodel.h"
#include <QListView>
#include <QTableView>

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

    QStringList list;
    list << QString("太阳") << QString("地球") << QString("月亮") << QString("木星");

    StringListModel model(list); //创建模型

    model.insertRows(3, 2);
    model.removeRows(5, 1);

    QListView listView;        //创建列表视图
    listView.setModel(&model); //视图设置模型
    listView.show();           //视图显示

    QTableView tableView;       //创建表格视图
    tableView.setModel(&model); //视图设置模型
    tableView.show();           //视图显示

    return app.exec();
}


结语:

时间: 2020-08-13

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值