用上下文属性将 C++ 对象嵌入 QML

警告: 通过在您的 QML 代码中使用上下文属性,您的 QML 代码与您编写代码时所想到的特定上下文之间产生了依赖关系。这就限制了代码的可重用性,因为在其他可能使用它的地方,上下文可能是不同的。此外,这种依赖关系没有声明。您从未import 上下文或以其他方式说明您的期望。因此,任何试图重复使用您的代码的人都很难发现重复使用的地方是否有适合您的代码的上下文。

警告: 在把 QML 代码加载到 QML 引擎之前,任何提前处理 QML 代码的工具都看不到上下文属性。上下文属性 Qt Quick CompilerqmllintQML Language Server对你的上下文属性一无所知,它们会认为对上下文属性的任何访问都是无条件访问

注意: 上下文属性通常可以用组件根对象上的常规属性,或用 C++ 中使用QML_SINGLETON 或 QML 中使用pragma Singleton 定义的单子(singletons)来代替。

当把 QML 对象载入 C++ 应用程序时,直接嵌入一些可在 QML 代码中使用的 C++ 数据可能很有用。例如,这样就可以在嵌入的对象上调用 C++ 方法,或使用 C++ 对象实例作为 QML 视图的数据模型。

将 C++ 数据注入 QML 对象的功能由QQmlContext 类实现。该类将数据公开到 QML 对象的上下文中,以便在 QML 代码范围内直接引用数据。

设置简单的上下文属性

例如,这里有一个 QML 项目,它引用了一个在当前范围内不存在的currentDateTime 值:

// MyItem.qml
import QtQuick

Text { text: currentDateTime }

加载 QML 组件的 C++ 应用程序可使用QQmlContext::setContextProperty() 直接设置currentDateTime 值:

QQuickView view;
view.rootContext()->setContextProperty("currentDateTime", QDateTime::currentDateTime());
view.setSource(QUrl::fromLocalFile("MyItem.qml"));
view.show();

注意: 由于在 QML 中评估的所有表达式都是在特定上下文中评估的,如果上下文被修改,该上下文中的所有绑定都将重新评估。因此,在应用程序初始化之外,应谨慎使用上下文属性,因为这可能会降低应用程序性能。

将对象设置为上下文属性

上下文属性可以保存QVariantQObject* 值。这意味着自定义 C++ 对象也可使用这种方法注入,这些对象可在 QML 中直接修改和读取。这里,我们修改了上面的示例,嵌入了一个QObject 实例,而不是QDateTime 值,QML 代码会调用对象实例上的一个方法:

C++
class ApplicationData : public QObject
{
    Q_OBJECT
public:
    Q_INVOKABLE QDateTime getCurrentDateTime() const {
        return QDateTime::currentDateTime();
    }
};

int main(int argc, char *argv[]) {
    QGuiApplication app(argc, argv);

    QQuickView view;

    ApplicationData data;
    view.rootContext()->setContextProperty("applicationData", &data);

    view.setSource(QUrl::fromLocalFile("MyItem.qml"));
    view.show();

    return app.exec();
}
QML
// MyItem.qml
import QtQuick

Text { text: applicationData.getCurrentDateTime() }

(注意,从 C++ 返回 QML 的日期/时间值可通过Qt.formatDateTime() 和相关函数进行格式化)。

如果 QML 项目需要从上下文属性接收信号,它可以使用Connections 类型与之连接。例如,如果ApplicationData 有一个名为dataChanged() 的信号,就可以使用Connections 对象中的onDataChanged 处理程序来连接这个信号:

Text {
    text: applicationData.getCurrentDateTime()

    Connections {
        target: applicationData
        onDataChanged: console.log("The application data changed!")
    }
}

上下文属性对在 QML 视图中使用基于 C++ 的数据模型很有用。请参阅以下示例:

演示在 QML 视图中使用QStringList,QList<QObject*> 基于模型和QAbstractItemModel

更多信息,请参阅QQmlContext 文档。

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.