QVariants 在 QML 中的C++和属性中的使用
Usage of QVariants in C++ and Properties in QML
当我在C++中为 QML 编写新组件时,我使用宏:
Q_PROPERTY(type READ getter WRITE setter NOTIFY signal)
在这里我可能会使用不同的类型s,例如int
或QVariant
.我想知道,我在这里不使用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
通过断点显示:
- p 未定义
- p 变为
string
- 分配了 p 值
- e 未定义
- e 变为类型
number
- e 值已分配
调用跟踪在视图中很复杂,但我可以看到使用了什么 QVariant 并使用了 QMetaType。
所以看起来任何通过Q_PROPERTY暴露的类型无论如何都会变成 QVariant。
我在QML上做了一些分析和实验,得出了这个答案,我认为这个答案很有可能:
-
实验:向对象添加属性
property var test
,并在C++中分析其元对象。我发现的是:QMetaObject::property()
方法总是返回一个QVariant
,如此方法的签名中所述,但QVariant
的类型始终设置为属性的类型。这意味着property int someInt
产生QVariant::int
,而property var someVar
产生QVariant::QVariant
- 这意味着至少在这里,我们必须解压缩两次值。+1 使用最合适的属性类型! -
实验:在包含
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
- QML:修改在不同QML文件(而非main.QML)中定义的子对象的属性
- Qt Quick-如何仅从c++代码与qml属性交互
- 如何将类的属性从 c++ 获取到 QML 中
- 是否可以在单独的线程中将 QObject 设置为 QML 上下文属性?
- 属性分配无效:"displayText"是文本字段 qml 中的只读属性
- QVariants 在 QML 中的C++和属性中的使用
- 在 QML 中更改父属性时更改子属性
- QML / C++可选属性
- QML 检测到属性宽度的绑定循环(TextMetrics 行为很奇怪)
- 可以从C++在QML上编写上下文属性吗?
- 当删除上下文属性中的QLIST对象时,QT QML应用程序崩溃
- 如何从 c++ 更改 QML 项的属性
- 使用 QAbstractListModel 分配 QML 布尔属性失败
- QML 无法分配给不存在的属性
- 从C++使用编译时安全性更改 QML 属性
- Javascript 函数作为从 c++ 定义的 QML 属性
- 从高度动态的C 数据模型中更新QML:计时器与属性绑定
- 从C 读取QML数组属性
- 如何使用 API 获取 QML 对象的 id 属性C++
- Qt-Qml连接到上下文属性的QObject属性的信号