Список доступа по индексу из QML - PullRequest
0 голосов
/ 23 апреля 2019

В моей программе есть древовидная архитектура объектов, к которой мне нужно получить доступ из QML. Я не могу понять, как я могу создать функцию получения Q_PROPERTY, которая позволила бы мне получить доступ к элементу в индексе по моему выбору. Функция выглядит так в C ++:

/**
 * @brief   Risk object getter function.
 * @param   index: The index of the risk from the \ref m_risks container.
 * @return  Pointer to the risk object if \p index is valid. Otherwise 0.
 */
CRiskData* CVessel::getRisk(const int index)
{
    if (index >= m_risks.length())
        return nullptr;

    return m_risks[index];
}

Но похоже, что эта система связи свойств QML <-> Qt допускает только метод получения, у которого нет входных параметров. Я попытался определить это так:

Q_PROPERTY(CRiskData* risk READ getRisk)

Я получаю ошибку компилятора, из-за которой не найдено подходящей функции:

moc_cvessel.cpp:122: error: no matching function for call to 'CVessel::getRisk()'
         case 0: *reinterpret_cast< CRiskData**>(_v) = _t->getRisk(); break;
                                                                   ^

Итак, MOC создал функцию без входных аргументов ... Есть ли способ обойти это? Цель состоит в том, чтобы иметь доступ к каждому элементу объекта со стороны QML в иерархическом порядке.

1 Ответ

1 голос
/ 25 апреля 2019

Глядя на ваш вопрос, я думаю, что вы должны использовать что-то, имеющее отношение к MVVM (https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel) или MVC. Поэтому вы должны создать свою собственную модель C ++, которую вы предоставляете QML, с помощью подкласса QAbstractItemModel. В этом модель, создайте метод Q_INVOKABLE в списке моделей:

cvessel.hpp:

#ifndef CVESSEL_HPP
#define CVESSEL_HPP

#include <QAbstractItemModel>
#include <QList>
class CRiskData;

class CVessel: public QAbstractItemModel
{
    Q_OBJECT

    public:
        CVessel(QObject * parent = nullptr);
        Q_INVOKABLE CRiskData* getRisk(const int index);
        static void declareQML();

        // QAbstractItemModel subclassing & rest of the header

    protected:
        QList<CRiskData *> m_risks;
};

#endif    // CVESSEL_HPP

cvessel.cpp:

#include "cvessel.hpp"
#include <QQmlEngine>
#include "criskdata.hpp"

CVessel::CVessel(QObject * parent = nullptr) :
    QAbstractItemModel(parent),
    m_risks()
{}

CRiskData* CVessel::getRisk(const int index);
{
    if (index >= m_risks.length())
        return nullptr;

    return m_risks[index];
}

void CVessel::declareQML() {
    qmlRegisterType<CVessel>("Bremen", 3, 14, "CVessel");
}

// Rest of implementation

RiskComponent.qml:

import QtQuick 2.12
import Bremen 3.14

Item {
    id: risk_component

    // ...

    TreeItem {
        id: the_tree
        model: CVessel {}

        // ...
    }

    // ...

    function usingARisk(riskIndex) {
        var risk = risk_component.the_tree.model.getRisk(riskIndex)

        // Using your risk on the QML side. For Example:
        console.log(qsTr("Risk level: %1").arg(risk.level))
    }

    // ...

}

main.cpp:

#include <QApplication>
#include <QQmlApplicationEngine>
#include "criskdata.hpp"
#include "cvessel.hpp"

int main(int argc, char ** argv) {
    QApplication app(argc, argv);

    //...

    CRiskData::declareQML();    // Of course if you use it on the QML side.
    CVessel::declareQML();

    //...

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
    int res = engine.rootObjects().isEmpty() ? -1 : app.exec();

    //...

    return res;
}

Для получения дополнительной информации о подклассе модели, смотрите страницу " Модель / Представление " на странице в документации Qt, особенно на модель " Справочник по подклассам"раздел .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...