使用 Context Properties 将 C++ 对象嵌入 QML
将 QML 对象加载到 C++ 应用程序时,直接嵌入一些可在 QML 代码中使用的 C++ 数据会很有用。例如,这使得可以对嵌入式对象调用 C++ 方法,或将 C++ 对象实例用作 QML 视图的数据模型。
QQmlContext 类可以将 C++ 数据注入到 QML 对象中,能够将 C++ 的数据暴露给 QML 对象的上下文,如此我们便能够在 QML 代码中取到来自于 C++ 的数据。
设置一个简单的 Context Property
该段以下面的代码为例来讲解如何设置简单的 Context Property,实现数据共享:
// MyItem.qml import QtQuick 2.0 Text { text: currentDateTime }
上面的这一行代码中的 text 属性引用了一个当前作用域中并不存在的 currentDateTime
变量值。我们希望这个值是从构建当前 qml 组件的 C++ 代码中传过来的。这要用到 QQmlContext::setContextProperty():
QQuickView view; view.rootContext()->setContextProperty("currentDateTime", QDateTime::currentDateTime()); view.setSource(QUrl::fromLocalFile("MyItem.qml")); view.show();
注意:QML 中所有表达式求值的过程都是在特定的上下文中进行的,如果上下文有变动,那么该上下文中的所有绑定都会被重新求值。因此,在除了应用初始化之外的地方都要小心使用 context properties,因其有可能导致应用性能下降。
将一个对象设置为 Context Property
Context properties 可以存储 QVariant 或 QObject* 值。这意味着自定义的 C++ 对象也可以使用这种方式注入上下文,实现在 QML 中直接读写。在下面的例子中,我们将一个 QObject 实例嵌入 QML ,然后在 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 2.0 Text { text: applicationData.getCurrentDateTime() } |
(注意:从 C++ 返回给 QML 的 date/time 值可以用 Qt.formatDateTime() 和相关函数格式化)
QML item 可以使用 Connections 类型连接到 context property,实现信号接收。例如:若 ApplicationData
有一个名为 dataChanged()
的信号,该信号则可以在 Connections 对象中与 onDataChanged
处理函数相连接,示例如下:
Text { text: applicationData.getCurrentDateTime() Connections { target: applicationData onDataChanged: console.log("The application data changed!") } }
Context properties 在 QML view 中使用 C++ 数据模型的场景中非常有用。参考下面的例子:
这些例子演示了如何在 QML view 中使用基于 QStringList,QList<QObject*> 的数据模型和 QAbstractItemModel。
另推荐阅读 QQmlContext 介绍文档,获取更多信息。