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

时间:2017-08-10 11:54:01

标签: c++ qt qml qt5

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

Q_PROPERTY(type READ getter WRITE setter NOTIFY signal)

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

To quote the documentation:

  

如果没有QVariant,这对于QObject :: property()和数据库工作等都是一个问题。

那么 - 如果我在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中有一个Component,很可能我有一个属性绑定到多个其他属性,所以读取经常发生。所以在Q_PROPERTY QVariant中输入类型是个好主意,否则我会把它包裹很多次。

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

2 个答案:

答案 0 :(得分:1)

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

我刚刚在调试器中使用断点运行我的app,看看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. 类型
  7. e赋值
  8. 调用跟踪在视图中很复杂,但我可以看到使用QVariant和使用QMetaType。

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

答案 1 :(得分:0)

我对QML进行了一些分析和实验,让我得到了这个答案,我认为很可能:

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

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

  3.   

    带回家消息:虽然QML中的属性被处理为QVariant,但使用更好的拟合类型声明属性是有益的,否则结果不是{{1但也许是QVariant::int

    在我的实验中,我发现没有任何QVariant::QVariant::int飞来飞去的痕迹,当我找到QJSValues

    时我不会感到惊讶而不是QVariant::QVariant