No.58~60 自定义模型类

QStandardItemModel是一个通用的模型类:

1、能够以任意的方式组织数据(线性、非线性);

2、数据组织的基本单位为数据项(QStandardItem);

3、每一个数据项能够存储多个数据状态(附加数据角色);

4、每一个数据项能够对数据状态进行控制(可编辑,可选。。。)。

组织结构如下:


新类型引入:QVariant

1QVariant 是一个用于封装的类型;

2、QVariant 能够表示大多数常见的值类型;

3、QVariant 每次只能封装(保存)单一类型的值;

4、QVariant 意义在于能够设计“返回类型可变的函数”。


应用实例如下:

#include <QCoreApplication>
#include <QVariant>
#include <QPoint>
#include <QDebug>

QVariant func()  //返回值的类型此处是不确定的
{
    QVariant ret;

    return ret;
}

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

    QVariant v1(1);
    QVariant v2(3.14);
    QVariant v3("520");
    QVariant v4(QPoint(10, 10));
    QVariant v5;

    qDebug() << v1.type();
    qDebug() << v1.typeName();
    qDebug() << v1.toInt();
    qDebug() << v1.value<int>();

    qDebug() << endl;

    qDebug() << v2.type();
    qDebug() << v2.typeName();
    qDebug() << v2.toInt();
    qDebug() << v2.toDouble();
    qDebug() << v2.value<int>();

    qDebug() << endl;

    qDebug() << v3.type();
    qDebug() << v3.typeName();
    qDebug() << v3.toInt();
    qDebug() << v3.value<int>();
    qDebug() << v3.value<QString>();


    qDebug() << endl;

    bool ok = true;

    qDebug() << v4.type();
    qDebug() << v4.typeName();
    qDebug() << v4.toInt(&ok);
    qDebug() << ok;
    qDebug() << v4.toPoint();

    qDebug() << endl;

    qDebug() << v5.isValid();

    return a.exec();
}

运行结果:


注:在对QVariant类型的数据进行操作时,应首先检查其是否可用。(IsValid()函数)

工程中常用的模型设计:

1、解析数据源中的数据(数据库,网络,串口,等);

2、将解析后的数据存入QStandardItem对象中;

3、根据数据间的关系在QStandardItemModel对象中组织数据项;

4、选择合适的视图显示数据项。


实例分析:


分析思路如下:

系统架构图:

工程中常用的数据应用架构分为4层:

数据层,数据表示层,数据组织层,数据显示层。


系统核心类图:



具体实现:


将每个功能层做成一个相对应的类,从而根据具体类实现相应的功能。

1、DataSource类的设计与实现:

设置数据源并读取数据;对数据进行解析后生成数据对象。

.h文件如下:

#include <QObject>
#include <QList>
#include "ScoreInfo.h"

class DataSource : public QObject
{
    Q_OBJECT

    QList<ScoreInfo> m_data;  //创建ScoreInfo类型的一个QList对象
    bool parse(QString line, ScoreInfo& info);

public:
    explicit DataSource(QObject* parent = 0);
    bool setDataPath(QString path);
    QList<ScoreInfo> fetchData();
    int count();

};

2、ScoreInfo类的设计与实现:

封装数据源中的一组完整数据;提供返回具体数据值的接口函数。

.h文件如下:

#include <QObject>
#include <QString>

class ScoreInfo : public QObject
{
    Q_OBJECT

    QString m_id;
    QString m_name;
    int m_score;
public:
    explicit ScoreInfo(QObject *parent = 0);
    explicit ScoreInfo(QString id, QString name, int score);
    ScoreInfo(const ScoreInfo& obj);
    ScoreInfo& operator =(const ScoreInfo& obj);
    QString id();
    QString name();
    int score();

};

3、ScoreInfoModel类的设计与实现:

使用标准模型类QStandardItemModel作为成员;以ScoreInfo类对象为最小单位进行数据组织。

.h文件如下:

#include <QObject>
#include <QStandardItem>
#include <QTableView>
#include "ScoreInfo.h"

class ScoreInfoModel : public QObject
{
    Q_OBJECT

    QStandardItemModel m_model;
public:
    explicit ScoreInfoModel(QObject* parent = 0);
    bool add(ScoreInfo info);
    bool remove(int i);
    ScoreInfo getItem(int i);
    int count();
    void setView(QTableView& view);

signals:

public slots:
};

问题1:为什么DataScoure类中获取数据的方式是fetchData,而不是getData?

答:我们来看fetchData()的具体实现:

QList<ScoreInfo> DataSource::fetchData()  
{
    QList<ScoreInfo> ret = m_data;

    m_data.clear();

    return ret;
}

函数实现过程中,对取到的数据进行复制,并且将取到的数据删除,避免了数据的冗余。


问题2:这样架构一个数据应用程序有什么好处?

答:当数据源或者视图需要发生变化的时候,可以最小程度的减少代码改动,将改动可以具体到每一次。









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值