简体   繁体   English

QT模型内的QML模型? 并且可以通过qml访问

[英]QT qml model within a model? and accesible via qml

Is it possible to have a model within a model accessible via qml and each model are different classes 是否可以通过qml访问模型中的模型,并且每个模型都是不同的类

eg modelclass 1 has a vector of a subclass of model 例如,模型类1具有模型子类的向量
ie parent model can have many sub model 父模型可以有很多子模型

I tried to return a QAbstractItemModel as a role of QAbstractItemModel parent but it seems thats not possible any ideas of how to do these stuff?? 我试图返回一个QAbstractItemModel作为QAbstractItemModel父角色,但似乎没有关于如何做这些东西的任何想法?

[Edit 1] [编辑1]

The code : 编码 :

message.h message.h

#include <QAbstractListModel>
#include <QStringList>

//![0]
class Animal
{
 public:
     Animal(const QString &type, const QString &size);
 //![0]

     QString type() const;
     QString size() const;

 private:
     QString m_type;
     QString m_size;
  //![1]
};

class AnimalModel : public QAbstractListModel
{
  Q_OBJECT
  public:
  enum AnimalRoles {
    TypeRole = Qt::UserRole + 1,
    SizeRole
    };

 AnimalModel(QObject *parent = 0);
 //![1]

 void addAnimal(const Animal &animal);

 int rowCount(const QModelIndex & parent = QModelIndex()) const;

 QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) 
 const;

 protected:
    QHash<int, QByteArray> roleNames() const;
 private:
    QList<Animal> m_animals;
 //![2]
 };
//![2]

model.h 型号

#include <QAbstractListModel>
#include <QStringList>
#include <QDebug>
#include <message.h>

//![0]
//!
//!
class lister{
public:
    int id;
    AnimalModel *list=nullptr;
    void addlist(){
        list->addAnimal(Animal("Wolf", "Medium"));
        list->addAnimal(Animal("Polar bear", "Large"));
        list->addAnimal(Animal("Quoll", "Small"));
    }

};

class TestModel : public QAbstractListModel
{


public:

    enum EventRoles {
        ModelRole = Qt::UserRole + 1,
        IdRole = Qt::UserRole + 2
    };

    TestModel()
    {
        m_roles[ ModelRole] = "mm";
        m_roles[ IdRole] = "id";
        //  setRoleNames(m_roles);
    }

    int rowCount(const QModelIndex & = QModelIndex()) const
    {
        return mylist.count();
    }

    QVariant data(const QModelIndex &index, int role) const
    {
        if(role == IdRole)
        {
            return mylist.at(index.row()).id;
        }
        else if(role == ModelRole)
        {
            return QVariant::fromValue(mylist.at(index.row()).list);
        }
        return 0;
    }

    void addData(){
        static int a=0;
        qDebug()<<a<<"value";
        beginInsertRows(QModelIndex(), rowCount(), rowCount());
        lister temp;
        temp.id=a;
        temp.addlist();
        a++;
        mylist<<temp;
        temp.id=a;
        temp.addlist();
        a++;
        mylist<<temp;
        endInsertRows();
    }

    QHash<int, QByteArray> roleNames() const {
        QHash<int, QByteArray> roles;
        roles[ModelRole] = "mm";
        roles[IdRole] = "id";
        return roles;
    }
    QList<lister> mylist;
    QHash<int, QByteArray> m_roles;
};

message.cpp message.cpp

#include "message.h"

Animal::Animal(const QString &type, const QString &size)
    : m_type(type), m_size(size)
{
}

QString Animal::type() const
{
    return m_type;
}

QString Animal::size() const
{
    return m_size;
}

AnimalModel::AnimalModel(QObject *parent)
    : QAbstractListModel(parent)
{
}

void AnimalModel::addAnimal(const Animal &animal)
{
    beginInsertRows(QModelIndex(), rowCount(), rowCount());
    m_animals << animal;
    endInsertRows();
}

int AnimalModel::rowCount(const QModelIndex & parent) const {
    Q_UNUSED(parent);
    return m_animals.count();
}

QVariant AnimalModel::data(const QModelIndex & index, int role) const {
    if (index.row() < 0 || index.row() >= m_animals.count())
        return QVariant();

    const Animal &animal = m_animals[index.row()];
    if (role == TypeRole)
        return animal.type();
    else if (role == SizeRole)
        return animal.size();
    return QVariant();
}

//![0]
QHash<int, QByteArray> AnimalModel::roleNames() const {
    QHash<int, QByteArray> roles;
    roles[TypeRole] = "type";
    roles[SizeRole] = "size";
    return roles;
}
//![0]

main.cpp main.cpp

#include "model.h"

#include <QGuiApplication>
#include <qqmlengine.h>
#include <qqmlcontext.h>
#include <qqml.h>
#include <QtQuick/qquickitem.h>
#include <QtQuick/qquickview.h>

//![0]
int main(int argc, char ** argv)
{
    QGuiApplication app(argc, argv);

    TestModel model;
//    model.addAnimal(Animal("Wolf", "Medium"));
//    model.addAnimal(Animal("Polar bear", "Large"));
//    model.addAnimal(Animal("Quoll", "Small"));
    model.addData();
    model.addData();
        model.addData();


        qRegisterMetaType<AnimalModel*>("AnimalModel*" );

    QQuickView view;
    view.setResizeMode(QQuickView::SizeRootObjectToView);
    QQmlContext *ctxt = view.rootContext();
    ctxt->setContextProperty("myModel", &model);
//![0]

    view.setSource(QUrl("qrc:view.qml"));
    view.show();

    return app.exec();
}

view.qml view.qml

import QtQuick 2.0
import QtQml 2.0

ListView {
    anchors.fill: parent
    model: myModel //this is your main model

    delegate:
        Rectangle {
        height: 100
        width: 100
        color: "red"
        Text {
            id: cc
            text: id
        }

        ListView {
            anchors.fill: parent
            model: mm //the internal QVariantList
            delegate: Rectangle {
                anchors.right:  parent.right
                width: 50
                height: 50
                color: "green"
                border.color: "black"
                Text {
                    text: type //role to get data from internal model
                }
            }
        }
    }
}

Yes its fine. 是的,很好。

You need to return a pointer to your sub model object wrapped in a variant, 您需要返回一个指向包装在变量中的子模型对象的指针,

QVariant::fromValue(&subModel) 

You probably also need to register your model pointer with Metatype system using 您可能还需要使用以下方法向Metatype系统注册模型指针

qRegisterMetaType<MySubModelClass*>("MySubModelClass*" );

Here is an implementation with DelegateModel introducet in Qt 5.13 这是Qt 5.13中引入的DelegateModel的实现

import QtQuick 2.12
import QtQuick.Window 2.12
import com.example 1.0
import QtQml.Models 2.12
import QtQuick.Layouts 1.3

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

    DelegateModel
    {
        id: delegateModel
        model : MyModel{}

        delegate:ColumnLayout
        {
            width: parent.width
            Row
            {
                Text
                {
                    text: qsTr("Word:")
                    color: "red"
                }
                Text
                {
                    text: word
                }
            }
            Text
            {
                color: "red"
                text: qsTr("In Other Languages:")
            }
            ListView {
                model: translations
                height: 50
                delegate:
                    Rectangle
                {
                    height: 20
                    width: 100
                    Text {
                        anchors.right: parent.right
                        text: translations[index]
                    }
                }
            }
        }
    }

    ListView
    {
        model : delegateModel
        anchors.centerIn: parent
        width: parent.width/2
        height: parent.height
    }

}

MyModel.h 我的模型

#include <QAbstractListModel>

class MyModel : public QAbstractListModel
{
    Q_OBJECT
public:
    enum WordRoles
    {
        WordRole = Qt::UserRole+1,
        TranslationsModelRole
    };
    explicit MyModel(QObject* parent=nullptr);
    int rowCount(const QModelIndex &parent) const override;
    QVariant data(const QModelIndex &index, int role) const override;
    QHash<int, QByteArray> roleNames() const override;
private:
    struct Word
    {
        QString word;
        QStringList translations;
    };
    QList<Word> m_words;
};

MyModel.cpp MyModel.cpp

#include<MyModel.h>
#include <QList>

MyModel::MyModel(QObject *parent)
    :QAbstractListModel(parent)
{
    m_words={{"apple",{"elma","Apfel"}},
            {"ball",{"top","ball"}},
            {"friend",{"arkadas","freund"}}
        };
}

int MyModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent)
    return m_words.size();
}

QVariant MyModel::data(const QModelIndex &index, int role) const
{
    if(index.row()>=m_words.size() || index.row()<0)
        return QVariant();
    if ( role == WordRole)
    {
        return m_words[index.row()].word;
    }
    else if ( role == TranslationsModelRole)
    {
        return m_words[index.row()].translations;
    }
    return QVariant();
}

QHash<int, QByteArray> MyModel::roleNames() const
{
    QHash<int,QByteArray> roles;
    roles[WordRoles::WordRole] = "word";
    roles[WordRoles::TranslationsModelRole]="translations";
    return roles;
}

main.cpp main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <MyModel.h>
int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);
    qmlRegisterType<MyModel>("com.example",1,0,"MyModel");
    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();
}

Result is ListView inside ListViev: 结果是ListViev中的ListView:

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM