Тип данных QML Custom List - PullRequest
0 голосов
/ 18 мая 2019

Мне интересно, возможно ли в QML определить собственный класс списка, который можно использовать в QML.

В настоящее время я анализирую более или менее сложные структуры данных и транслирую их в дерево QVariantMap, QVariantList и QVariants.
Однако эти типы могут включать в себя довольно большие массивы большинства основных типов (uint8_t, uint16_t, ..., uint64_t, int8_t, ..., float, double).
Я бы предпочел, чтобы мне не приходилось копировать эти массивы в QVariantList по очевидным причинам производительности.
Можно ли как-нибудь обернуть массив в пользовательский тип, который обеспечивает доступ к элементам так, как QML понимает, и, таким образом, копирует элементы в QVariant только по запросу?

Я пытался зарегистрировать тип с помощью Q_INVOKABLE operator[], но, похоже, это не сработало.

Обновление: Чтобы уточнить немного больше. Я знаю, что могу создать класс с пользовательскими свойствами, которые могут предоставить методы доступа. Однако с помощью метода QVariantList я могу сделать следующее в QML

onMessage: {
  element.text = message.poses[0].position.x
}

Я ищу способ обернуть массив таким образом, чтобы фактическая реализация не была заметна в QML, то есть он должен выглядеть как обычный массив, к которому можно обращаться с помощью оператора скобок и т. Д. Тот факт, что он на самом деле просто обертка должна быть полностью прозрачной для пользователя.

1 Ответ

0 голосов
/ 19 мая 2019

Вы можете заключить свой массив в QObject и передать его как свойство контекста в часть QML.

Например, чтобы использовать вектор целых чисел в QML:

class ArrayInterface: public QObject
{
    Q_OBJECT
    using value_t = int;
public:
    ArrayInterface(std::vector<value_t> const& src): QObject(), source(src)
    {}
    // Can be called from QML
    Q_INVOKABLE int get(int idx) const
    {
        return source[idx];
    }
private:
    std::vector<value_t> const& source;
};
int main(int argc, char *argv[]) {
    QGuiApplication app(argc, argv);

    std::vector<int> vec = {12, 4, 5, 7};
    ArrayInterface data(vec);

    QQuickView view;
    view.rootContext()->setContextProperty("myArray", &data);
    view.setSource(QUrl(QStringLiteral("qrc:/main.qml")));
    view.show();

    return app.exec();
}
Item {
    height: 500
    width: 500
    Text { text: myArray.get(0) }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...