模型中的QT qml模型?并可通过qml访问

时间:2017-06-25 15:16:14

标签: c++ qt qml

是否可以通过qml访问模型中的模型,并且每个模型都是不同的类

例如,modelclass 1具有模型
的子类的向量 父模型可以有很多子模型

我试图将didSelectRow作为QAbstractItemModel父母的角色返回,但似乎不可能有任何关于如何做这些事情的想法?

[编辑1]

代码:

message.h

QAbstractItemModel

model.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]

message.cpp

#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;
};

的main.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]

view.qml

#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();
}

2 个答案:

答案 0 :(得分:2)

是的,没关系。

您需要返回一个指向包含在变体

中的子模型对象的指针
QVariant::fromValue(&subModel) 

您可能还需要使用

在Metatype系统中注册模型指针
qRegisterMetaType<MySubModelClass*>("MySubModelClass*" );

答案 1 :(得分:1)

这是在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

#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

#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();
}

结果是ListViev中的ListView:

enter image description here