如何有效地将单个对象的多个 C++ 数据成员公开给 QML?

Posted

技术标签:

【中文标题】如何有效地将单个对象的多个 C++ 数据成员公开给 QML?【英文标题】:How to efficiently expose many C++ data members of a single object to QML? 【发布时间】:2013-12-10 01:22:29 【问题描述】:

我有一个包含许多数据成员的 C++ 对象指针。我需要它们都可以在 QML 中使用。一种明显的方法是为每个成员创建一个Q_PROPERTY,以便可以通过 QML 单独访问它们。但是,如果我们谈论的是几十个数据成员,那是Q_PROPERTY 的很多行,更不用说在 QML 中也必须将它们作为单独的属性单独处理(尤其是在为每个处理“on changed”信号时)属性)。

我想知道是否可以创建一个包含我需要的所有数据成员的Q_PROPERTY。但我不清楚the types that QML supports 与您可以在Q_PROPERTY 中列出的类型之间明显不匹配。例如,在 QML 中,我们有一个基本的 string,但它在 C++ 中的对应列表 Q_PROPERTY 必须是 QString

 Q_PROPERTY(QString datastring READ showdata NOTIFY datastringChanged)
  //in QML, `datastring` is just a plain string

是否会有更复杂的属性,例如可以轻松匹配的列表或数组? QML 有一个list 类型,C++ 有一个QList,但它们是一回事吗?在哪里可以找到 C++ 和 QML 之间兼容类型的列表?

另一方面,为每个数据成员设置单独的 Q_PROPERTY 可能会带来更好的性能(我的数据很大并且经常变化),因为 QML 可能不需要解析任何内容。

【问题讨论】:

【参考方案1】:

是否会有更复杂的属性,如列表或数组,可以 容易匹配? QML 有一个列表类型,C++ 有 QList,但它们是 这些是一样的吗?在哪里可以找到兼容类型的列表 C++ 和 QML 之间的区别?

看看C++/JS data conversion help page。我认为列表遗漏了QList<QObject*>也是可能的。

另一方面,每个数据成员都有单独的 Q_PROPERTY 可能会有更好的性能(我的数据很大而且经常 改变)因为 QML 可能不需要解析任何东西。

也许,是的,取决于您的性能需求。当从 QML/JS 访问时,C++ QList 会被转换为 javascript 列表。这确实是一些转换开销。此外,如果列表中的某个项目发生更改,您需要为完整属性发出通知信号,并且需要重新评估使用列表的每个 JS 绑定,这将再次进行许多列表转换。拥有更细粒度的属性可能会更好,但这确实取决于。

顺便说一句,Qt 5.1 现在有了MEMBER,这使得编写 Q_PROPERTY 更容易一些。

【讨论】:

感谢您指出 MEMBER 我以前没见过。所以它基本上只允许直接访问数据成员而无需作为 getter 的中介函数? 是的。基本上moc 会为你自动生成getter 和setter,你只需要提供一个成员变量和一个NOTIFY 信号。 需要注意的是Q_PROPERTY 使用MEMBER 并定义了NOTIFY 信号,如果Qt 没有定义setter,Qt 会在属性值从QML 更改时发出此信号。如果直接在 C++ 中更改成员值,则不会发出任何信号。

以上是关于如何有效地将单个对象的多个 C++ 数据成员公开给 QML?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 cython 将 python 类公开给 c++

如何正确地将 C 数组传递给 C#?

如何有效地将大型数据框拆分为多个拼花文件?

如何有效地将大字符串从 Python 传递到 C++ 扩展方法?

如何线程安全地将并行进程中的数据收集到单个对象中?

C++ - 使用 std::list,如何打印对象私有成员的链表?