Отображение модели в модели или List модели ввиде листа (ListView)?

Имеется структура данных - коэффициенты, распределенные по группам разных размеров, т.е. по сути

list<list<int>>

Нужно создать UI в QML и соответствующие c++/-модели для возможности просмотра и редактирования коэффициентов.

UI

Опишите необходимую структуру приложения и код !точнее модели и их использование!, ибо я не осознаю все ли правильно я понимаю. Из того что рабочее - то что на скрине. Текущий код (не рабочий) кинул на гит: https://github.com/zel1b08a/QmlTest. (в комите ранее лежит состояние приложения на котором я остановился в данный момент). Далее накидаю скетчей что и как я вижу - как должно быть..

  1. Модель Bank - с++ модель, которая собственно хранит данные одной отдельной группы коэффициентов (bank.h).
    struct Coefficient {
        quint32 value;
        bool operator==(const Coefficient& o) const;
    };
    Q_DECLARE_METATYPE(Coefficient)

    class Bank : public QObject
    {
        Q_OBJECT

    public:
        explicit Bank(QVector<Coefficient> coefficients = QVector<Coefficient>(), QObject *parent = nullptr);

        QVector<Coefficient> coefficients() const;
        void setCoefficients(QVector<Coefficient> coefficients);

    // ...

    private:
        QVector<Coefficient> _coefficients;
    };
  1. Абстрактная модель BankModel для него, через которую будет реализовано изменения данных (bankmodel.h):
class BankModel : public QAbstractListModel
{
    Q_OBJECT
    Q_PROPERTY(Bank* bank READ bank WRITE setBank)

public:
    enum {
        CoefficientRole = Qt::UserRole
    };

    explicit BankModel(QObject *parent = nullptr);

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

    QVariant data(const QModelIndex &index, int role = CoefficientRole) const override;
    bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;

    Qt::ItemFlags flags(const QModelIndex& index) const override;
    QHash<int, QByteArray> roleNames() const override;

    Bank* bank() const;
    void setBank(Bank* bank);

    // ...

private:
    Bank* _bank;
};
  1. Общая модель конфигов (банков), наследуемая от QObject (configmodel.h):
class ConfigModel : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QList<Bank*> banks READ banks WRITE setBanks NOTIFY banksChanged)

public:
    explicit ConfigModel(QList<Bank*> banks = QList<Bank*>(), QObject *parent = nullptr);

    QList<Bank*> banks() const;
    void setBanks(QList<Bank*> banks);

    // ...

signals:
    void banksChanged(QList<Bank*> banks);

private:
    QList<Bank*> _banks;
};

Как я понимаю, в qml model view можно передать теперь по свойству весь конфиг (инициализирую его в main.cpp), в его делегат можно будет пробросить банк и в нем создать внутренний listview с делегатом для каждого коэффициента.

Блок для отображения всех конфигов (main.qml):

// ...
ListView {
    anchors.fill: parent
    model: cfg.banks
    delegate: BankView {}
}
// ...

BankView.qml:

Rectangle {
    // ...
    property int bankId: model.index
    property int coefficientsNumber: 0
    Column {
        // ...
        BankViewHeader {  // просто чекбокс
            id: checker
            text: qsTr("Bank " + bank_view.bankId)
            // ...
        }
        BankViewDescription {
            id: description
            isOpened: checker.checked
            // ...
        }
    }
}

BankViewDescription.qml

RowLayout {
    // ...
    property bool isOpened: false
    Row {
        RowLayout {
            // ...
            ListView {
                // ...
                model: BankModel {
                    bank: model.bank // ???
                }
                delegate: Row {
                    TextField {
                        text: coefficient // my bank role
                        // ...
                    }
                }
            }
        }
    }
}

main.cpp:

#include "bank.h"
#include "bankmodel.h"
#include "configmodel.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    qmlRegisterType<BankModel>("Config", 1, 0, "BankModel");
    qmlRegisterType<ConfigModel>("Config", 1, 0, "ConfigModel");
    qmlRegisterUncreatableType<Bank>("Config", 1, 0, "Bank", QStringLiteral("Don't!"));

    ConfigModel cfg;
    cfg.setBanks(QList<Bank*>()
                 << new Bank(QVector<Coefficient>({ Coefficient { 11 }, Coefficient { 21 }, Coefficient { 31 }, Coefficient { 41 } }))
                 // ...
                 << new Bank(QVector<Coefficient>({ Coefficient { 15 }, Coefficient { 25 }, Coefficient { 35 }, Coefficient { 45 } }))
                 );

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty(QStringLiteral("cfg"), &cfg);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

ПЫСЫ: Ломаю голову уже с месяц, везде одни простые примеры, никакой нормальной документации и примеров для сложных моделей.


Ответы (0 шт):