【问题标题】:Does QT use dynamic_cast for QML properties?QT 是否将 dynamic_cast 用于 QML 属性?
【发布时间】:2020-10-19 09:29:10
【问题描述】:

我在 QT 中遇到了奇怪的行为。

假设您有一个基本控制器:

class BaseController : public QObject
{
    Q_OBJECT

public:
    BaseController() = default

protected:
    inline BaseNode * getRoot() const noexcept { return root; }

protected:
    BaseNode * root;
};

还有额外控制器:

class ExtraController final : public BaseController
{
    Q_OBJECT

    Q_PROPERTY( BaseNode * root READ getRoot NOTIFY changed )

public:
    ExtraController() { root = new ExtraNode(); }

signals:
    void changed();
};

关键时刻,有两种类型的节点。 BaseNode 只是一个具有 "id" 属性的抽象类。 ExtraNode 是 BaseNode 的继承者,具有属性 "name"。

在 qml 我使用类似的东西:

Label {
    text: extraController.root.name // property root - calls getRoot() in BaseController
}

还有它的作品!尽管 BaseController 的函数 getRoot() 返回指向 BaseNode 的指针,但它没有“name”属性。问题是:它是如何工作的?如何在 qml 中使用派生类的属性? qt 是否执行 dynamic_cast 左右?

【问题讨论】:

    标签: c++ qt qml


    【解决方案1】:

    Qt 使用its own meta object system。这就是您需要 MOC 和 Q_OBJECT 宏的原因。 因此,Qt“知道”每个对象在运行时具有哪些属性,并将这些知识也用于 QML。

    在 C++ 方面,您可以通过 QObject::property() 看到这一点:

    返回对象名称属性的值。 如果不存在此类属性,则返回的变体无效。 通过metaObject()dynamicPropertyNames() 提供有关所有可用属性的信息。

    请注意,对象具有的属性与其类型无关(请参阅上面对动态属性的引用)。访问对象的属性时,对象引用/指针的类型无关紧要 - 将始终检索正确的元对象和属性列表。

    还有一个qobject_cast利用元对象系统向下转换对象。

    【讨论】:

    • 我知道MOC系统。 Q_PROPERTY 声明中甚至还有 FINAL 关键字,但就我而言,我根本没有属性。它不是关于覆盖属性或向下转换的对象。它的 QML 做了一些我试图理解的魔法......
    • 我的回答解释说 Qt 使用自己的元对象系统来确定运行时每个对象的可用属性。首先,您使用root 访问器获取对象。然后 QML 读取属性name。此时对象的类型并不重要。您有一个对象,它有其特定的一组属性。 Qt 会找到属性name 只是因为它在那里。
    • 请注意,访问属性总是通过方法调用运行。将其视为一种方法getProperty(propertyName),它始终存在于您看不到的每个 QObject 中。该方法将始终有效。这与在基指针上调用重写的方法相同(方法调用在运行时使用 vtable 调度)。
    • 我在答案中添加了这些细节。
    • 谢谢!现在有道理了。
    猜你喜欢
    • 2018-07-24
    • 1970-01-01
    • 1970-01-01
    • 2019-04-13
    • 1970-01-01
    • 1970-01-01
    • 2021-05-13
    • 2015-04-15
    • 1970-01-01
    相关资源
    最近更新 更多