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

警告:通过在您的 QML 代码中使用上下文属性,您使您的 QML 代码依赖特定上下文,这限制了代码的可重用性,因为其他可能使用您的代码的地方上下文可能不同。此外,这种依赖并未声明。您从未导入上下文或以其他方式声明您的预期。因此,尝试重用您的代码的人将难以确定重用位置是否有足够的上下文来满足您的代码。

警告:上下文属性在工具程序中是不可见的,这些工具程序在您将代码加载到 QML 引擎之前会处理 QML 代码。Qt 快速编译器、qmllint 和 QML 语言服务器都没有关于您的上下文属性的了解,并将对上下文属性的任何访问视为无资格访问

注意:通常可以通过以下任一方式替换上下文属性:组件根对象上的常规属性,或使用 C++ 中的QML_SINGLETON在 C++ 中定义的单例,或在 QML 中使用pragma Singleton定义的单例。

在将 QML 对象加载到 C++ 应用程序时,直接嵌入一些可以从 QML 代码内部使用的 C++ 数据可能很有用。例如,可以在嵌入的对象上调用 C++ 方法,或使用 C++ 对象实例作为 QML 视图的数据模型。

通过QQmlContext类可以使向 QML 对象注入 C++ 数据成为可能。这个类将数据暴露给 QML 对象的上下文,这样数据就可以在 QML 代码的作用域中直接引用。

设置简单上下文属性

例如,这里有一个引用了当前作用域中不存在的 currentDateTime 值的 QML 项目

// MyItem.qml
import QtQuick

Text { text: currentDateTime }

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

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 视图中使用基于 QStringListQList<QObject*>-based 模型以及 QAbstractItemModel

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

© 2024 Qt 公司有限。此处包含的文档贡献属于各自所有者的版权。此处提供的文档根据免费软件基金会发布的 GNU 自由文档许可协议版本 1.3 的条款提供。Qt 及相关标志是芬兰的 Qt 公司和/或世界其他国家的商标。所有其他商标均属于各自所有者。