Отображение модели в модели или List модели ввиде листа (ListView)?
Имеется структура данных - коэффициенты, распределенные по группам разных размеров, т.е. по сути
list<list<int>>
Нужно создать UI в QML и соответствующие c++/-модели для возможности просмотра и редактирования коэффициентов.
Опишите необходимую структуру приложения и код !точнее модели и их использование!, ибо я не осознаю все ли правильно я понимаю. Из того что рабочее - то что на скрине. Текущий код (не рабочий) кинул на гит: https://github.com/zel1b08a/QmlTest. (в комите ранее лежит состояние приложения на котором я остановился в данный момент). Далее накидаю скетчей что и как я вижу - как должно быть..
- Модель 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;
};
- Абстрактная модель 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;
};
- Общая модель конфигов (банков), наследуемая от 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();
}
ПЫСЫ: Ломаю голову уже с месяц, везде одни простые примеры, никакой нормальной документации и примеров для сложных моделей.
