QML 自定义列表数据类型

Posted

技术标签:

【中文标题】QML 自定义列表数据类型【英文标题】:QML Custom List Data type 【发布时间】:2019-05-18 18:56:34 【问题描述】:

我想知道是否可以在 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 中并不明显,这意味着它应该看起来像一个可以使用括号运算符等访问的普通数组。事实上它实际上是只是一个包装器应该对用户完全透明。

【问题讨论】:

您能提供您的数据样本吗?另外,您想对这些数据做什么(显示、处理等)? 它是一个库,因此数据和用例可能因用户而异,但它通常是一个树结构,例如它可能是一个包含两个成员的姿势:一个位置和一个方向。该位置由 x、y 和 z 组成,它们是叶子(例如 Floats)。但它也可能包含一个相当大的数组的图像。就个人而言,我想不出很多 QML 中需要数组数据的用例,但如果可能的话,我不希望限制用例。 显然,我不想将大型数组复制到 qvariantlist,因为在大多数用例中它们无论如何都不会被访问,但我想提供访问其内容的选项,因此,我m 正在寻找包装数组的选项,以便可以从 qml 访问它而无需复制它。 【参考方案1】:

您可以将数组包装在 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) 

【讨论】:

感谢您的回答。我确实知道上下文属性。对不起,我应该更具体并更新了问题。我希望 QML 端的行为就像它是 QVariantList / JS 数组一样。数组被包装以进行延迟加载的事实不应该被用户注意到。 您不能在 QML 中为您的 C++ 对象使用运算符(我猜,因为 JS 不支持运算符重载)。您只能调用函数。但是,您可以包装 QVarianList 并且只有一个函数 get()at()

以上是关于QML 自定义列表数据类型的主要内容,如果未能解决你的问题,请参考以下文章

Qt 使用自定义 QObject 类型调用 qml 函数

Qml中关于TreeView 简单model自定义类型实现

Qml中关于TreeView 简单model自定义类型实现

如何使C ++将值列表或其他复杂类型返回到QML

Python面向对象进阶示例--自定义数据类型

自定义 C 类型与 C 类型列表和列表类型