I have followed this tutorial : https://resources.qt.io/resources-by-content-type-videos-demos-tutorials/using-c-models-in-qml-tutorial
This was usefull to create my c++ class to manage my LightModel
Now I want to re-use this tutorial where I have a model inside 2 other repeaters in cascade. The issue is that my qml code instantiate LightModel objects inside repeaters so I don't have access to these instances from main.cpp
I used qmlRegisterType to give qml the ability to create several objects from my LightModel class.
main.cpp
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
qmlRegisterType<Light>("Light",1,0,"Light");
qmlRegisterType<LightModel>("Light", 1,0,"LightModel");
qmlRegisterUncreatableType<Light>("Light", 1, 0, "LightList", QStringLiteral("LightList should not be created in QML"));
QQmlApplicationEngine engine;
MainWindow w;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
w.show();
return app.exec();
}
light.h
#ifndef LIGHT_H
#define LIGHT_H
#include <QObject>
#include <QVector>
struct LightItem{
QString description;
int value;
int bornInf;
int bornSup;
int decimals; //1, 10
bool enabled;
};
class Light : public QObject
{
Q_OBJECT
public:
explicit Light(QObject *parent = nullptr);
QVector<LightItem> items() const;
bool setItemAt(int index, const LightItem &item);
signals:
void preItemAppended();
void postItemAppended();
void preItemRemoved(int index);
void postItemRemoved();
private:
QVector<LightItem> mItems;
};
#endif // LIGHT_H
lightmodel.h
#ifndef LIGHTMODEL_H
#define LIGHTMODEL_H
#include <QAbstractListModel>
class Light;
class LightModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(Light *list READ list WRITE setList)
Q_PROPERTY(int ledMode READ getLedMode WRITE setLedMode)
public:
explicit LightModel(QObject *parent = nullptr);
enum{
DescriptionRole = Qt::UserRole,
ValueRole,
BornInfRole,
BornSupRole,
Decimals,
EnableRole
};
// Basic functionality:
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
// Editable:
bool setData(const QModelIndex &index, const QVariant &value,
int role = Qt::EditRole) override;
Qt::ItemFlags flags(const QModelIndex& index) const override;
virtual QHash<int, QByteArray> roleNames() const override;
Light *list() const;
void setList(Light *list);
int getLedMode() const;
void setLedMode(int value);
private:
Light *mList;
int ledMode;
};
#endif // LIGHTMODEL_H
main.qml
StackLayout {
id: lampChose
currentIndex: gridLamps.indexImage
Repeater {
id: repeater1
model: 24
StackLayout {
id: lampStack
currentIndex: tabBarNm.currentIndex
Repeater {
id: repeater2
model: 7
Column {
id: columnSpinBoxtConfLeds
Repeater {
id: repeaterParametersSpinBoxesLEDs
model: LightModel {
id: lightModel
list: light }
SpinBox {
id: spinBoxTest
visible: true
editable: true
value: model.value
from: model.bornInf
to: model.bornSup
stepSize: 1
onValueChanged: {
model.value = value
}
}
}
}
}
}
}
My LightModel class is implemented like ToDoModel in the tutorial exemple : https://github.com/mitchcurtis/todo-list-tutorial/tree/chapter-11
So the question is : how can I access from C++ the content of the LightModel objects because the 24x7 instances are created by .qml file.
Thanks a lot for your time
I've found the solution to my problem : stop using repeaters with StackLayout.
My editable content is stored inside an array, set as context property inside my main.cpp and the view get the value corresponding to the current index
light.h
#ifndef LIGHT_H
#define LIGHT_H
#include <QObject>
class LightV2 : public QObject
{
Q_OBJECT
public:
explicit LightV2(QObject *parent = nullptr);
public slots:
Q_INVOKABLE int getArrayValue(int indexLamp, int indexLight, int indexField);
Q_INVOKABLE int getBornInf(int indexLamp, int indexLight, int indexField);
Q_INVOKABLE int getBornSup(int indexLamp, int indexLight, int indexField);
Q_INVOKABLE int getDecimal(int indexLamp, int indexLight, int indexField);
Q_INVOKABLE void setArrayValue(int indexLamp, int indexLight, int indexField, int value);
private:
QString mDescription;
int mValue;
int mArrayValue[24][7][6];
int mBornInf[24][7][6];
int mBornSup[24][7][6];
int mDecimal[24][7][6];
};
#endif // LIGHTV2_H
main.cpp
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
qmlRegisterType<GeneralConf>("Light", 1,0, "GeneralConf");
QQmlApplicationEngine engine;
LightV2 lights;
MainWindow w;
engine.rootContext()->setContextProperty("lights", &lights);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
w.show();
return app.exec();
}
finally : solution in main.qml
Column {
id: columnSpinBoxtConfLeds
x:110
y:0
width:200
spacing: 10
Repeater {
id: repeaterParametersSpinBoxesLEDs
model: 6
SpinBox {
id: spinBoxTest
property int decimals: lights.getDecimal(gridLamps.indexImage,tabBarNm.currentIndex, model.index);
property int decimalPresent:{
if (decimals == 10){
1
}
else{
0
}
}
width : 150
height: 25
focusPolicy: Qt.TabFocus
wheelEnabled: false
visible: true
editable: true
enabled: {
console.log("spinbox index:",model.index)
if (model.index == 2 || model.index == 3){
if(comboBoxMode.currentIndex >=1){
1
}
else{
0
}
}
else if (model.index >= 4){
if(comboBoxMode.currentIndex >=2){
1
}
else{
0
}
}
else{
1
}
}
value: lights.getArrayValue(gridLamps.indexImage,tabBarNm.currentIndex, model.index)
from : lights.getBornInf(gridLamps.indexImage,tabBarNm.currentIndex, model.index)
to : lights.getBornSup(gridLamps.indexImage,tabBarNm.currentIndex, model.index)
stepSize: 1
textFromValue: function(value, locale){
return Number(value / decimals).toLocaleString(locale, 'f',decimalPresent)
}
valueFromText: function(text,locale){
return Number.fromLocaleString(locale, text) * decimals
}
onValueChanged: {
lights.setArrayValue(gridLamps.indexImage,tabBarNm.currentIndex, model.index, value);
console.log(lights.getArrayValue(gridLamps.indexImage,tabBarNm.currentIndex, model.index));
}
}
to conclude : this is how I managed to resolve my issue :
lights.getArrayValue(gridLamps.indexImage,tabBarNm.currentIndex, model.index)
and
lights.setArrayValue(gridLamps.indexImage,tabBarNm.currentIndex, model.index, value);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.