qml-model

 视图项模型:如果是listModel,可以继承QAbstractListModel

QAbstractListModel

        提供了一个抽象模型,可以对其进行子类化以创建一维列表模型。
        QAbstractListModel 为模型提供了一个标准接口,将它们的数据表示为一个简单的非分层项目序列。它不能直接使用,但必须是子类。
        由于模型提供了比 QAbstractItemModel 更专业的接口,因此不适合与树视图一起使用;如果要为此目的提供模型,则需要将 QAbstractItemModel 子类化。如果您需要使用多个列表模型来管理数据,则将 QAbstractTableModel 子类化可能更合适。
        可以通过子类化此类并实现所需的最少功能来创建简单的模型。例如,我们可以实现一个简单的基于 QStringList 的只读模型,它为 QListView 小部件提供字符串列表。在这种情况下,我们只需要实现 rowCount() 函数返回列表中的项目数,并实现 data() 函数从列表中检索项目。
由于模型表示一维结构,因此 rowCount() 函数返回模型中的项目总数。 columnCount() 函数实现了与各种视图的互操作性,但默认情况下通知视图模型仅包含一列。

        在继承 QAbstractListModel 时,您必须提供 rowCount() 和 data() 函数的实现。表现良好的模型还提供了 headerData() 实现。
        如果您的模型在 QML 中使用并且需要 roleNames() 函数提供的默认角色以外的角色,则必须覆盖它。
        对于可编辑列表模型,您还必须提供 setData() 的实现,并实现 flags() 函数,以便它返回一个包含 Qt::ItemIsEditable 的值。
        请注意,QAbstractListModel 提供了 columnCount() 的默认实现,它通知视图此模型中只有一列项目。
        为可调整大小的类列表数据结构提供接口的模型可以提供 insertRows() 和 removeRows() 的实现。在实现这些函数时,调用适当的函数很重要,以便所有连接的视图都知道任何更改:
insertRows() 实现必须在将新行插入数据结构之前调用 beginInsertRows(),之后必须立即调用 endInsertRows()。
        removeRows() 实现必须在从数据结构中删除行之前调用 beginRemoveRows(),并且之后必须立即调用 endRemoveRows()。
        注意:模型子类化参考中提供了一些用于子类化模型的一般准则。
        另请参阅模型类、模型子类化参考、QAbstractItemView、QAbstractTableModel 和项目视图拼图示例。

自定义model

如下展示数据:

其中main.qml:

自定义了一个TestModel:

"testmodel.h"
#ifndef TESTMODEL_H
#define TESTMODEL_H

#include <QObject>
#include <QAbstractListModel>
#include <QQmlListProperty>

class TestListItem:public QObject{
    Q_OBJECT

    Q_PROPERTY(QString name WRITE setName READ getName NOTIFY nameChanged)
    Q_PROPERTY(int  value WRITE setValue READ getValue NOTIFY valueChanged)
public:
    using QObject::QObject;

    void setName(const QString &name);
    QString getName()const ;

    void setValue(int value);
    int getValue() const;
    ~TestListItem();
signals:
    void nameChanged();
    void valueChanged();

private:
    QString _name;
    qint32 _value;
};


class TestModel:public QAbstractListModel
{
    Q_OBJECT

    Q_PROPERTY(QQmlListProperty<TestListItem> datas  READ datas NOTIFY datasChanged)
    enum Role{
        Name = Qt::DisplayRole + 1,
        Value
    };
signals:
    void datasChanged();
public:
    using QAbstractListModel::QAbstractListModel;
    using TestItemListType = QList<TestListItem *>;

    TestModel();

    Q_INVOKABLE void append(const QJsonObject &item) ;
    QHash<int, QByteArray> roleNames() const override;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const  override;
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;

    QQmlListProperty<TestListItem> datas();
    static  void AppendFunction(QQmlListProperty<TestListItem> *,TestListItem *);
    static  int CountFunction(QQmlListProperty<TestListItem> *);
    static  TestListItem * AtFunction(QQmlListProperty<TestListItem> *,int);
    static  void  ClearFunction(QQmlListProperty<TestListItem> *);
private:
    mutable QHash<int, QByteArray> _roles;
    QList<TestListItem *>  _items;
};

#endif // TESTMODEL_H

"testmodel.cpp"
#include "testmodel.h"
#include <QJsonObject>
#include <QDebug>

void TestListItem::setName(const QString &name){
    if (_name != name){
        _name = name;
        emit nameChanged();
    }
}
QString TestListItem::getName()const {
    return _name;
}

void TestListItem::setValue(int value){
    if (_value != value){
        _value = value;
        emit valueChanged();
    }

}
int TestListItem::getValue() const{
    return _value;
}

TestListItem::~TestListItem(){
        qDebug() << "TestModel::~TestModel";
}
TestModel::TestModel()
{

    qDebug() << "TestModel::TestModel";
}


void TestModel::append(const QJsonObject &item){


    qDebug() << "TestModel::append";
    auto tmp = new TestListItem(this);
    if (!tmp){
        return;
    }

    tmp->setName(item.value("name").toString());
    tmp->setValue(item.value("value").toInt());
    _items.append(tmp);

    endResetModel();
}

/*
    对应delegate:Text{
        text:name + " " + value
    }中的 name value

*/
QHash<int, QByteArray> TestModel::roleNames() const {
    if (_roles.isEmpty()){

        _roles.insert(Role::Name,"name");
        _roles.insert(Role::Value,"value");
    }

    return _roles;
}
QVariant TestModel::data(const QModelIndex &index, int role) const  {


    qDebug() << "TestModel::data ";
    if (!index.isValid()){
        return QVariant();
    }

    if (role == Role::Name){
        return QVariant(_items[index.row()]->getName());
    }
    else if (role == Role::Value){

        return QVariant(_items[index.row()]->getValue());
    }


    return QVariant();
}
int TestModel::rowCount(const QModelIndex &parent) const {

    return _items.count();
}

QQmlListProperty<TestListItem> TestModel::datas(){

       qDebug() << "TestModel::datas ";
    return   QQmlListProperty<TestListItem>(this,&_items,
                                       &TestModel::AppendFunction,
                                       &TestModel::CountFunction,
                                       &TestModel::AtFunction,
                                       &TestModel::ClearFunction);

}

void TestModel::AppendFunction(QQmlListProperty<TestListItem> *items,TestListItem *item){
       qDebug() << "TestModel::AppendFunction ";
    static_cast<TestItemListType*>(items->data)->append(item);
}
int TestModel::CountFunction(QQmlListProperty<TestListItem> *items){

    return static_cast<TestItemListType*>(items->data)->count();

}
TestListItem * TestModel::AtFunction(QQmlListProperty<TestListItem> *items,int index){

    return static_cast<TestItemListType*>(items->data)->at(index);

}
void  TestModel::ClearFunction(QQmlListProperty<TestListItem> *items){

    static_cast<TestItemListType*>(items->data)->clear();
}






main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "testmodel.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);

    qmlRegisterType<TestListItem>("TestModule",1,0,"TestListItem");
    qmlRegisterType<TestModel>("TestModule",1,0,"TestModel");
    QQmlApplicationEngine engine;
    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();
}

main.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import TestModule 1.0

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")


    ListView{
        anchors.fill: parent
        model:TestModel{
            id:testmodel
            datas: [
            TestListItem{
                name: "zhangsan"
                value: 123
                },
            TestListItem{
                name: "zhangsan1"
                value: 1234
                }
            ]

        }

        delegate: Text{
        text:name + "  " + value

            MouseArea{
                anchors.fill: parent
                onClicked: {
                  testmodel.append({name:"qml",value:123})
                }
            }
        }

    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值