【问题标题】:QML property of property of C++ objectC++ 对象属性的 QML 属性
【发布时间】: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)。在示例中,toStringQ_INVOKABLE,频率在非工作情况下返回 QObject 派生的 CFrequency 对象的副本。

-- 编辑:进一步的发现--

当我将频率属性更改为返回 CFrequency* 而不是 CFrequency 时,它也不起作用。当我得到TypeError: Cannot call method 'toQString' of undefined 时,情况似乎是一样的。 CFrequency 单独工作,但 QML 不理解 myatcstation.frequency 是具有 toString 的频率对象。

【问题讨论】:

    标签: c++ qt qml


    【解决方案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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-25
      • 2013-11-10
      • 1970-01-01
      • 2017-05-26
      • 2023-04-05
      • 2019-06-08
      • 1970-01-01
      相关资源
      最近更新 更多