【译】使用 Context Properties 将 C++ 对象嵌入 QML (Qt 5.11)

651 阅读2分钟

原文链接:doc.qt.io/archives/qt…

当在 C++ 应用中加载 QML 对象时,通常都会有在 QML 和 C++ 之间进行交互和共享数据的需求。

通过 QQmlContext 类可以将 C++ 数据注入到 QML 对象中: QQmlContext 能够将 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;
// 下面这样就将 QDateTime::currentDateTime() 暴露为了 qml 上下文中的一个可读取(求值)的属性
view.rootContext()->setContextProperty("currentDateTime", QDateTime::currentDateTime());
view.setSource(QUrl::fromLocalFile("MyItem.qml"));
view.show()

注意:QML 中所有表达式求值的过程都是在特定的上下文中进行的,如果上下文有变动,那么该上下文中的所有绑定都会被重新求值。因此,在除了应用初始化之外的地方都要小心使用 context properties ,因其有可能导致应用性能下降.

将一个对象设置为 Context Property

Context properties 可以存储 QVariantQObject* 值。这意味着自定义的 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::fromLoacaFile("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("App data changed!")
	}
}

Context properties 在 QML view 中使用 C++ 数据模型的场景中非常有用。参考下面的例子:

String ListModel

Object ListModel

AbstractItemModel

这些例子演示了如何在 QML view 中使用基于 QStringList, QList<QObject*> 的数据模型和 QAbstractItemModel

另推荐阅读 QQmlContext 原文译文)介绍文档,获取更多信息