QVariants 在 QML 中的C++和属性中的使用

Usage of QVariants in C++ and Properties in QML

本文关键字:属性 QML 中的 C++ QVariants      更新时间:2023-10-16

当我在C++中为 QML 编写新组件时,我使用宏:

Q_PROPERTY(type READ getter WRITE setter NOTIFY signal)

在这里我可能会使用不同的类型s,例如intQVariant.我想知道,我在这里不使用QVariant是否有任何好处。

引用文档:

如果没有 QVariant,这对 QObject::p roperty(( 和数据库工作等来说将是一个问题。

那么 - 如果我读取或写入 QML 端的属性会发生什么?
我的猜测是,它调用:

QVariant QObject::property(const char *name) const
bool QObject::setProperty(const char *name, const QVariant &value)

这意味着,我的属性,整齐地定义为我的 getter 返回int, dobule, QString, ...将被包装为QVariant从 C++ 传输到 QML - 如果我从一开始就将其定义为QVariant,这个过程将是不必要的。

如果我在 QML 中有一个组件,那么我很可能有一个属性到多个其他属性的绑定,所以阅读经常发生。因此,最好将类型包含在 QVariantQ_PROPERTY,否则我会将其包装很多次。

在C++方面,我可能会决定是否经常阅读。如果是这样,我将原始数据类型中的值缓冲以在C++内访问,但是在值更改时创建QVariant,因此对于 QML,没有必要多次创建它。-还是这是自动发生的?QML 对象是否将其所有属性值缓冲为 QVariant?

不,我想你没有。至少如果你把它暴露给QML或从QAbstractListModel任何类型的子类中使用(数据函数返回的所有值和返回类型都是QVariant(

我刚刚通过带有断点的调试器运行我的应用程序,以查看Q_PROPERTY变量会发生什么。刚刚在函数中添加了截取MouseArray onClicked简单代码:

var p = ExContact.phone;
var e = ExContact.status;

电话QString,状态qint8通过断点显示:

  1. p 未定义
  2. p 变为string
  3. 分配了 p 值
  4. e 未定义
  5. e 变为类型number
  6. e 值已分配

调用跟踪在视图中很复杂,但我可以看到使用了什么 QVariant 并使用了 QMetaType。

所以看起来任何通过Q_PROPERTY暴露的类型无论如何都会变成 QVariant。

我在QML上做了一些分析和实验,得出了这个答案,我认为这个答案很有可能:

  1. 实验:向对象添加属性property var test,并在C++中分析其元对象。我发现的是:
    QMetaObject::property()方法总是返回一个QVariant,如此方法的签名中所述,但QVariant的类型始终设置为属性的类型。这意味着property int someInt产生QVariant::int,而property var someVar产生QVariant::QVariant- 这意味着至少在这里,我们必须解压缩两次值。+1 使用最合适的属性类型!

  2. 实验:在包含inline QVariant(QVariant &&other) Q_DECL_NOTHROW : d(other.d)inline QVariant &operator=(QVariant &&other) Q_DECL_NOTHROW的行处将断点添加到QVariant(QtCore/qvariant.h( 的源文件中,我发现当我在 QML 中更改QVariant的值时可能会调用断点。
    在 QML 中,我添加了一个Button,它在单击时增加了其x位置。
    不出所料,每当我单击按钮时,都会重复调用这两行。不幸的是,我错过了洞察力,QVariant在哪里改变了,以及其中一个是否确实是我们该职位的财产。但是,我不认为Qt会在后端的某个地方有大量QVariant,所以我认为我的假设很可能是正确的,并且在QML端,属性作为QVariant处理。


带回家的消息:尽管 QML 中的属性是按QVariant处理的,但使用更好的拟合类型声明属性是有益的,否则结果不是QVariant::int,而是QVariant::QVariant::int


在我的实验中,我没有发现QJSValues飞来飞去的痕迹,在有property var ...时,我不会惊讶地发现而不是QVariant::QVariant