Qt-自定义c++模型应用于qml中

Qt-自定义c++模型应用于qml中,第1张

概述

      虽然QML已经提供了几种比较常见的模型,但是依然不足以应对应用中可能出现的情况。


所以才需要自定义c++模型,然后可以在QML中使用,这有助于将c++数据模型或其他复杂的数据集暴露给QML。



      C++模型类可以是QStringList、QObjectList或者QAbstractItemModel ,前面两个对于暴露简单数据集是非常有用的,而QAbstractItemModel则为更复杂的模型提供了灵活的解决方案。


本章使用QAbstractItemModel自定义模型,其他有兴趣的可以自行了解。


实现

话不多说,直接上代码 (ps:自己做的小demo)

//  !!!!!StudentModel.h
#include <QAbstractListModel>
#include <QJsonObject>
#include <QJsonArray>

//子类化QAbstractListModel
class StudentModel : public QAbstractListModel{
    Q_OBJECT

public:
    enum Student_Role{ //定义数据的角色
        IdRole = Qt::UserRole+1, //UserRole表示合法位置的起始位置
        NameRole,
        SexRole,
        AgeRole,
        SchoolRole,
        StuNumberRole
    };

    Q_ENUM(Student_Role) //必须有这一句,使枚举类可以使用

    explicit StudentModel(QObject *parent = nullptr);
    ~StudentModel();


    //必须重写的三个方法
    //第一个方法返回数据条目数
    //第二个方法返回指定角色的数据
    //第三个方法返回数据与角色的映射关系
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
protected:
     QHash<int, QByteArray> roleNames() const override;

public slots:
	//对数据的基本 *** 作
     void setStudent(const QJsonArray StudentJsonArray); //初始化数据
     void insertStudent(const QJsonObject &StudentJsonobject,int &index); //添加数据
     void removeStudent(int &index); //移除数据

private:
	 //以下是数据源
     QList<int> m_idList;
     QList<QString> m_nameList;
     QList<QString> m_sexList;
     QList<int> m_ageList;
     QList<QString> m_schoolList;
     QList<QString> m_schoolNumberList;
};
//  !!!!!StudentModel.cpp
#include "StudentModel.h"
#include <QDebug>
StudentModel::StudentModel(QObject *parent)
    :QAbstractListModel(parent)
{
}

StudentModel::~StudentModel()
{
}


int StudentModel::rowCount(const QModelIndex &parent) const{
    return m_idList.size();
}

QVariant StudentModel::data(const QModelIndex &index, int role) const{
    if(!index.isValid()){
        return QVariant();
    }
    switch (role) {
    case IdRole:
        return m_idList.at(index.row());
    case NameRole:
        return m_nameList.at(index.row());
    case SexRole:
        return m_sexList.at(index.row());
    case AgeRole:
        return m_ageList.at(index.row());
    case SchoolRole:
        return m_schoolList.at(index.row());
    case StuNumberRole:
        return m_schoolNumberList.at(index.row());
    default:
        return QVariant();
    }
}

QHash<int, QByteArray> StudentModel::roleNames() const{
    static QHash<int, QByteArray> roles{
        {IdRole,"id"},
        {NameRole,"name"},
        {SexRole,"sex"},
        {AgeRole,"age" },
        {SchoolRole,"school"},
        {StuNumberRole,"stuNo" }
    };
    return roles;
}

//注入初始数据
void StudentModel::setStudent(const QJsonArray StudentJsonArray){
    beginResetModel();  //重置数据必须遵循的规则,表示开始
    m_idList.clear();
    m_nameList.clear();
    m_sexList.clear();
    m_ageList.clear();
    m_schoolList.clear();
    m_schoolNumberList.clear();
    for(int i=0;i<StudentJsonArray.size();i++){
        QJsonObject obj = StudentJsonArray.at(i).toObject();
        m_idList << obj["id"].toInt();
        m_nameList << obj["name"].toString();
        m_sexList << obj["sex"].toString();
        m_ageList << obj["age"].toInt();
        m_schoolList << obj["school"].toString();
        m_schoolNumberList << obj["stuNo"].toString();
    }
    endResetModel(); //重置数据必须遵循的规则,表示结束
}

//增加数据
void StudentModel::insertStudent(const QJsonObject &StudentJsonobject,int &index){
    if(index <0 || index > rowCount()) //无效处理
        return;
    int id = StudentJsonobject.value(QLatin1String("id")).toInt();
    QString name = StudentJsonobject.value(QLatin1String("name")).toString();
    QString sex = StudentJsonobject.value(QLatin1String("sex")).toString();
    int age = StudentJsonobject.value(QLatin1String("age")).toInt();
    QString school = StudentJsonobject.value(QLatin1String("school")).toString();
    QString stuNo = StudentJsonobject.value(QLatin1String("stuNo")).toString();


	//插入数据需遵循的规则,表示开始
    beginInsertRows(QModelIndex(),index,index); //第一个参数表示在顶级根(由于是列表结构所以表示当前列表的根),第二个参数表示起始位置,第三个参数表示结束位置,由于只有一列,所以两者都一样
    m_idList.insert(index,id);
    m_nameList.insert(index,name);
    m_sexList.insert(index,sex);
    m_ageList.insert(index,age);
    m_schoolList.insert(index,school);
    m_schoolNumberList.insert(index,stuNo);
    endInsertRows();    //插入数据需遵循的规则,表示结束
}

//移除数据
void StudentModel::removeStudent(int &index){
    if(index < 0 || index > rowCount())return;
    beginRemoveRows(QModelIndex(),index,index); //移除数据需遵循的规则,表示开始
    m_idList.removeAt(index);
    m_nameList.removeAt(index);
    m_sexList.removeAt(index);
    m_ageList.removeAt(index);
    m_schoolList.removeAt(index);
    m_schoolNumberList.removeAt(index);
    endRemoveRows();	//移除数据需遵循的规则,表示结束
}
// !!!!!main.cpp
#include <QQmlApplicationEngine>
#include <QQmlComponent>
#include <QQmlContext>
#include <QGuiApplication>
#include "StudentModel.h"


int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
    QGuiApplication app(argc,argv);
    QQmlApplicationEngine engine;

    StudentModel model;
    //下面两种方法均可
    //第一种是直接在上下文环境直接注册进去一个实例
    //第二种将模型类注册进去,以至于模型类可以像QML组件一样实例化
    engine.rootContext()->setContextProperty("$Model",&model); //注入模型
//    qmlRegisterType("Com.Lc.Classes", 1, 0, "StudentModel");
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

至此,c++自定义模型结束了,可以在QML进行使用了。


是不是都是套路?
简单总结一下实现c++自定义模型的步骤:

  • 第一步:子类化QAbstractItemModel。


    重写它的三个方法。


  • 第二步:定义角色枚举,并使用Q_ENUM()方法
  • 第三步:定义数据源
  • 第四步:根据角色定义和数据源,重新实现它的三个方法
  • 第五步(可选):如有需要增删改查 *** 作,需遵循它的规则!!!
  • 第六步:在QML中注册c++模型类

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/langs/563783.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-03
下一篇 2022-04-03

发表评论

登录后才能评论

评论列表(0条)

保存