当我在C ++中为QML编写新组件时,我使用宏:
Q_PROPERTY(type READ getter WRITE setter NOTIFY signal)
在这里,我可能会使用不同的类型,例如int
或QVariant
。我想知道,如果我在这里不使用QVariant
有任何好处。
如果没有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?
答案 0 :(得分:1)
不,我想你没有。至少如果你将它公开给QML或者在QAbstractListModel
中使用任何类型的子类(数据函数和返回类型返回的所有值都是QVariant
)
我刚刚在调试器中使用断点运行我的app,看看Q _ PROPERTY
变量会发生什么。刚刚在MouseArray onClicked
函数中添加了简单的代码:
var p = ExContact.phone;
var e = ExContact.status;
手机为QString
,状态为qint8
通过断点显示:
string
number
调用跟踪在视图中很复杂,但我可以看到使用QVariant和使用QMetaType。
所以看起来通过Q_PROPERTY暴露的任何类型都会变成QVariant ..
答案 1 :(得分:0)
我对QML进行了一些分析和实验,让我得到了这个答案,我认为很可能:
实验:向对象添加属性property var test
,并在C ++中分析其元对象。我找到的是:
QMetaObject::property()
方法始终返回QVariant
,如此方法的签名中所述,但QVariant
的类型始终设置为属性的类型。这意味着property int someInt
会产生QVariant::int
而property var someVar
产生QVariant::QVariant
- 这意味着至少在这里,我们必须将值解包两次。 +1使用最合适的属性类型!
实验:在包含QVariant
和QtCore/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。
带回家消息:虽然QML中的属性被处理为
QVariant
,但使用更好的拟合类型声明属性是有益的,否则结果不是{{1但也许是QVariant::int
。
在我的实验中,我发现没有任何QVariant::QVariant::int
飞来飞去的痕迹,当我找到QJSValues
QVariant::QVariant