C++ 对象属性的 QML 属性
Posted
技术标签:
【中文标题】C++ 对象属性的 QML 属性【英文标题】:QML property of property of C++ object 【发布时间】:2013-10-15 00:30:28 【问题描述】:我是 QML 新手,在访问 C++ 对象的 property.property 时遇到问题:
C++、频率和电台都是Qt元类型注册对象:
CStation *station = new CStation(...); // QObject
CFrequency *frequency = new CFrequency(..); // QObject
QQmlContext *qmlContext = viewer.rootContext();
qmlContext->setContextProperty("myatcstation", station);
qmlContext->setContextProperty("myfrequency", frequency);
QML:
RowLayout ....
TextField
text: myatcstation.toQString(true)
.... text: myfrequency.toQString(true)
这行得通,但是当我写:text: myatcstation.frequency.toQString(true)
我确实得到TypeError: Object [object Object] has no method 'toQString'
frequency
是类CStation
的属性设置为Q_PROPERTY(CFrequency frequency READ getFrequency)
C++ 中的交叉检查有效:
CFrequency test = station->property("frequency").value<CFrequency>();
-- 编辑:弗兰克的回答--
这两个类都是从QObject
派生的,它不是教科书上的,因为它们是可复制的。我知道Identity vs value 的情况。
频率基本上是一个值对象,但我已将其设为基于QObject
,因此我可以使用它的属性(请参阅Any chance to use non QObject classes with QML)。在示例中,toString
是 Q_INVOKABLE
,频率在非工作情况下返回 QObject
派生的 CFrequency
对象的副本。
-- 编辑:进一步的发现--
当我将频率属性更改为返回 CFrequency*
而不是 CFrequency
时,它也不起作用。当我得到TypeError: Cannot call method 'toQString' of undefined
时,情况似乎是一样的。 CFrequency
单独工作,但 QML 不理解 myatcstation.frequency
是具有 toString
的频率对象。
【问题讨论】:
【参考方案1】:CFrequency
不是我假设的 QObject,否则您不会按值而是按指针返回它。要使 `toQString() 可以从 QML 调用,它必须是 Q_INVOKABLE 或插槽,这意味着 CFrequency 也必须是 QObject。
如果一个电台只有一个频率,请考虑将相关信息移动到电台对象中,即将您需要的频率信息作为属性添加到 CStation。
要在频率更改时获取更新,请考虑使用 Q_PROPERTY(QString frequencyAsString READ frequencyAsString NOTIFY frequencyAsStringChanged)
等属性,而不是 toQString()
。属性通过属性绑定“内置”了更新机制,而没有好的方法告诉 QML 它应该再次调用 toQString,因为频率发生了变化。
【讨论】:
好提示,在上面添加了一些信息。问题是,如果 CFrequency(这是一个 QObject 按值返回)作为副本返回(即使不希望复制 QObjects),它是否可以工作。【参考方案2】:我解决了一个类似的问题:
class TopObject : public QObject
Q_OBJECT
Q_PROPERTY(ValueObject* theValue ...
...
class ValueObject : public QObject
Q_OBJECT
Q_PROPERTY(QString value ...
...
在主应用程序中:
qRegisterMetaType<ValueObject>("ValueObject");
qmlRegisterType<ValueObject>("com.name.comp", 1, 0, "ValueObject");
...->setContextProperty("topObject", new TopObject());
在qml代码中:
import com.name.comp 1.0
...
text: topObject.theValue.value
...
两者都需要,将属性 (ValueObject) 作为指针返回并使用 qmlRegisterType 注册。
另见Exchange Data and Objects between C++ and QML and vice versa
【讨论】:
以上是关于C++ 对象属性的 QML 属性的主要内容,如果未能解决你的问题,请参考以下文章
在 C++ 中循环读取 QML 对象(CheckBox)属性:总是相同的值
C++ 类以时尚 TypeError 暴露于 QML 错误:对象的属性“...”不是函数