从 C++ 暴露状态到 QML
通常希望从 C++ 暴露一些属性,以便在特定组件中的所有 QML 元素、模块中的所有 QML 元素甚至是所有的 QML 元素可以使用。您可以通过引入单例或者向选定组件的根对象添加属性来实现。
使用单例
如果您想将多个全局属性暴露给模块中的所有元素或所有元素整体,您可以在 C++ 中定义一个单例。为此,请将 QML_ELEMENT 或 QML_NAMED_ELEMENT 宏以及 QML_SINGLETON 宏添加到包含要暴露为 Q_PROPERTY 声明的属性的类中
// Singleton.h class Singleton : public QObject { Q_OBJECT Q_PROPERTY(int thing READ thing WRITE setThing NOTIFY thingChanged FINAL) QML_ELEMENT QML_SINGLETON public: Singleton(QObject *parent = nullptr) : QObject(parent) {} int thing() const { return m_value; } void setThing(int v) { if (v != m_value) { m_value = v; emit thingChanged(); } } signals: void thingChanged(); private: int m_value = 12; };
现在您可以通过从任何导入此模块的 QML 代码中访问单例的 thing 属性
import QtQml QtObject { objectName: "The thing is " + Singleton.thing }
如果您将您的 QML 文件放在与模块相同的目录中(强烈推荐),则在您的模块内部隐式导入它时可用。您不需要显式导入任何内容。如果不这样的话,或者您想从模块中访问 thing 属性,您需要导入单例所属的模块。
为了从 C++ 中设置属性值,您可能需要检索单例实例。为此,您可以使用 QQmlEngine::singletonInstance。首选的方法是将模块和类型名称作为参数传递
Singleton *singleton = engine->singletonInstance<Singleton *>("MyModule", "Singleton"); singleton->setThing(77);
使用对象属性
如果您想仅将属性暴露给特定组件中的 QML 元素,您可以将它们作为常规属性添加到组件的根对象上。为了确保它们在所有情况下都真正设置,您可以将其设置为 Required Properties。您可能将您的 QML 组件编写如下
pragma ComponentBehavior: Bound import QtQuick Window { id: root visible: true required property int thing Text { anchors.fill: parent text: "The thing is " + root.thing } component Inner: QtObject { objectName: "I can see " + root.thing + " because I'm bound." } }
我们为组件的根元素使用了 ID,并从任何内部对象通过 ID 和名称进行属性引用。为了安全地将根元素的 ID 传递到任何嵌套组件中,我们使用了 ComponentBehavior。
然后,在 C++ 中,当您从此类组件创建对象时,您需要确保调用 QQmlComponent::createWithInitialProperties、QQmlApplicationEngine::setInitialProperties 或 QQuickView::setInitialProperties 来初始化属性。例如
QQmlEngine engine; QQmlComponent component(&engine, "MyModule", "RequiredProperties"); QScopedPointer<QObject> o(component.createWithInitialProperties({ {"thing", 11} }));
这假设您的模块 URI 是 MyModule,并且该模块在 QML 导入路径中可用。
© 2024 Qt公司有限公司。本文件的文档贡献属于各所有者的版权。本文档受自由软件基金会发布的GNU自由文档许可协议版本1.3的条款约束。Qt及其相关标志是芬兰及其它国家和地区Qt公司的商标。所有其他商标均为其各自所有者的财产。