Как я могу использовать класс модели С ++ в каскаде с 2 другими повторителями в файле .qml - PullRequest
0 голосов
/ 14 ноября 2018

Я прошел этот урок: https://resources.qt.io/resources-by-content-type-videos-demos-tutorials/using-c-models-in-qml-tutorial

Это было полезно для создания моего класса c ++ для управления моей LightModel

Теперь я хочу повторно использовать этот учебник, где у меня есть модель внутри 2 других ретрансляторов в каскаде. Проблема в том, что мой qml-код создает экземпляры объектов LightModel внутри ретрансляторов, поэтому у меня нет доступа к этим экземплярам из main.cpp

Я использовал qmlRegisterType, чтобы дать qml возможность создавать несколько объектов из моего класса LightModel.

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

Мой класс LightModel реализован как ToDoModel в учебном примере: https://github.com/mitchcurtis/todo-list-tutorial/tree/chapter-11

Таким образом, вопрос заключается в следующем: как я могу получить доступ из C ++ к содержимому объектов LightModel, поскольку экземпляры 24x7 создаются файлом .qml.

Большое спасибо за ваше время

1 Ответ

0 голосов
/ 15 ноября 2018

Я нашел решение моей проблемы: прекратить использование повторителей со StackLayout.

Моё редактируемое содержимое хранится внутри массива, устанавливается как свойство контекста внутри моего main.cpp, и представление получает значение, соответствующеек текущему индексу

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

наконец: решение в 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));
                    }
                }

В заключение: вот как мне удалось решить мою проблему:

lights.getArrayValue(gridLamps.indexImage,tabBarNm.currentIndex, model.index)

и

lights.setArrayValue(gridLamps.indexImage,tabBarNm.currentIndex, model.index, value);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...