Я создал минимальный рабочий пример. Надеюсь это будет понятно. Моя проблема в том, что я не могу создать модель для своего элемента верхнего уровня для дальнейшего доступа к элементам. Вот как выглядит архитектура объектов классов:
CTop
x times CMiddle
y times CBottom
Это древовидная архитектура. Вот код:
CBottom.h:
#ifndef CBOTTOM_H
#define CBOTTOM_H
#include <QObject>
#include <QtQml>
class CBottom : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
public:
CBottom(QObject *parent = nullptr) : QObject(parent)
{
}
CBottom(const QString& name, QObject *parent = nullptr) : QObject(parent)
{
qmlRegisterType<CBottom>("Bottom", 1, 0, "Bottom");
m_name = name;
}
QString name()
{
return m_name;
}
void setName(const QString& name)
{
if (name != m_name)
{
m_name = name;
emit nameChanged();
}
}
signals:
void nameChanged();
private:
QString m_name;
};
#endif // CBOTTOM_H
CMiddle.h:
#ifndef CMIDDLE_H
#define CMIDDLE_H
#include <QObject>
#include <QtQml>
#include <QVector>
#include "cbottom.h"
class CMiddle : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
public:
CMiddle(QObject *parent = nullptr) : QObject(parent)
{
}
CMiddle(const QString& name, const QStringList& bottoms, QObject *parent = nullptr) : QObject(parent)
{
qmlRegisterType<CMiddle>("Middle", 1, 0, "Middle");
m_name = name;
foreach (auto bottom, bottoms)
{
m_bottoms.append(new CBottom(bottom));
}
}
QString name()
{
return m_name;
}
void setName(const QString& name)
{
if (name != m_name)
{
m_name = name;
emit nameChanged();
}
}
signals:
void nameChanged();
private:
QString m_name;
QVector<CBottom*> m_bottoms;
};
#endif // CMIDDLE_H
CTop.h:
#ifndef CTOP_H
#define CTOP_H
#include <QObject>
#include <QtQml>
#include "cmiddle.h"
class CTop : public QObject
{
Q_OBJECT
public:
CTop(QObject *parent = nullptr) : QObject(parent)
{
}
CTop(const QStringList& middles, QObject *parent = nullptr) : QObject(parent)
{
qmlRegisterType<CTop>("Top", 1, 0, "Top");
int i = 0;
foreach (auto middle, middles)
{
QStringList bottoms;
bottoms.append("A" + QString(i));
bottoms.append("B" + QString(i));
bottoms.append("C" + QString(i));
i++;
m_middles.append(new CMiddle(middle, bottoms));
}
}
Q_INVOKABLE QVector<CMiddle*>& middles()
{
return m_middles;
}
Q_INVOKABLE CMiddle* middle(const int index)
{
return m_middles[index];
}
private:
QVector<CMiddle*> m_middles;
};
#endif // CTOP_H
main.c:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QString>
#include <QVector>
#include <QStringList>
#include <QVariant>
#include <QQmlContext>
#include "ctop.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QStringList middles;
middles.append("FirstMiddle");
middles.append("SecondMiddle");
CTop* top = new CTop(middles);
QQmlApplicationEngine engine;
QQmlContext *ctxt = engine.rootContext();
ctxt->setContextProperty("theTop", QVariant::fromValue(top));
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
main.qml:
import QtQuick 2.9
import QtQuick.Window 2.2
import Top 1.0
Window
{
width: 600
height: 400
visible: true
Repeater
{
model: theTop.middles();
delegate: txtComp;
}
Component
{
id: txtComp;
Text
{
text: name;
}
}
}
Вопрос в том, почему имя одного из CMiddle
объектов не отображается в коде QML? Я хотел получить компоненты CMiddle
(в качестве модели) из экспортированных в QML CTop
компонентов. Если бы этот код работал, я бы пошел дальше и создал другую модель для доступа к CBottom
объектам внутри каждого CMiddle
объекта.
Например, я заметил, что этот код QML работает:
import QtQuick 2.9
import QtQuick.Window 2.2
import Top 1.0
Window
{
width: 600
height: 400
visible: true
Repeater
{
model: theTop;
delegate: txtComp;
}
Component
{
id: txtComp;
Text
{
text: middle(0).name;
}
}
}
Это не имеет особого смысла, но показывает, что компонент CTop
правильно отображается в части QML.
Почему выходные данные Qvector
из CMiddle
указателей выступают в качестве модели в части QML?